Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F7147905
D5194.id18585.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Subscribers
None
D5194.id18585.diff
View Options
diff --git a/MANIFEST.in b/MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -3,3 +3,4 @@
include version.txt
include README.md
recursive-include swh py.typed
+include conftest.py
diff --git a/conftest.py b/conftest.py
new file mode 100644
--- /dev/null
+++ b/conftest.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2021 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+pytest_plugins = ["swh.auth.pytest_plugin"]
diff --git a/swh/auth/tests/conftest.py b/swh/auth/pytest_plugin.py
rename from swh/auth/tests/conftest.py
rename to swh/auth/pytest_plugin.py
--- a/swh/auth/tests/conftest.py
+++ b/swh/auth/pytest_plugin.py
@@ -5,7 +5,7 @@
from copy import copy
from datetime import datetime, timezone
-from typing import Optional
+from typing import Dict, Optional
from unittest.mock import Mock
from keycloak.exceptions import KeycloakError
@@ -13,23 +13,25 @@
from swh.auth.keycloak import KeycloakOpenIDConnect
-from .sample_data import (
- OIDC_PROFILE,
- RAW_REALM_PUBLIC_KEY,
- REALM,
- SERVER_URL,
- USER_INFO,
-)
-
class KeycloackOpenIDConnectMock(KeycloakOpenIDConnect):
"""Mock KeycloakOpenIDConnect class to allow testing
Args:
+ server_url: Server main auth url (cf.
+ :py:data:`swh.auth.tests.sample_data.SERVER_URL`)
+ realm_name: Realm (cf. :py:data:`swh.auth.tests.sample_data.REALM_NAME`)
+ client_id: Client id (cf. :py:data:`swh.auth.tests.sample_data.CLIENT_ID`)
auth_success: boolean flag to simulate authentication success or failure
- exp: expiration
+ exp: expiration delay
user_groups: user groups configuration (if any)
user_permissions: user permissions configuration (if any)
+ oidc_profile: Dict response from a call to a token authentication query (cf.
+ :py:data:`swh.auth.tests.sample_data.OIDC_PROFILE`)
+ user_info: Dict response from a call to userinfo query (cf.
+ :py:data:`swh.auth.tests.sample_data.USER_INFO`)
+ raw_realm_public_key: A raw ascii text representing the realm public key (cf.
+ :py:data:`swh.auth.tests.sample_data.RAW_REALM_PUBLIC_KEY`)
"""
@@ -42,6 +44,9 @@
exp: Optional[int] = None,
user_groups=[],
user_permissions=[],
+ oidc_profile: Optional[Dict] = None,
+ user_info: Optional[Dict] = None,
+ raw_realm_public_key: Optional[str] = None,
):
super().__init__(
server_url=server_url, realm_name=realm_name, client_id=client_id
@@ -49,7 +54,7 @@
self.exp = exp
self.user_groups = user_groups
self.user_permissions = user_permissions
- self._keycloak.public_key = lambda: RAW_REALM_PUBLIC_KEY
+ self._keycloak.public_key = lambda: raw_realm_public_key
self._keycloak.well_know = lambda: {
"issuer": f"{self.server_url}realms/{self.realm_name}",
"authorization_endpoint": (
@@ -81,7 +86,7 @@
"protocol/openid-connect/certs"
),
}
- self.set_auth_success(auth_success)
+ self.set_auth_success(auth_success, oidc_profile, user_info)
def decode_token(self, token):
options = {}
@@ -105,7 +110,12 @@
}
return decoded
- def set_auth_success(self, auth_success: bool) -> None:
+ def set_auth_success(
+ self,
+ auth_success: bool,
+ oidc_profile: Optional[Dict] = None,
+ user_info: Optional[Dict] = None,
+ ) -> None:
# following type ignore because mypy is not too happy about affecting mock to
# method "Cannot assign to a method affecting mock". Ignore for now.
self.authorization_code = Mock() # type: ignore
@@ -114,9 +124,15 @@
self.logout = Mock() # type: ignore
self.auth_success = auth_success
if auth_success:
- self.authorization_code.return_value = copy(OIDC_PROFILE)
- self.refresh_token.return_value = copy(OIDC_PROFILE)
- self.userinfo.return_value = copy(USER_INFO)
+ assert (
+ oidc_profile is not None
+ ), "You must provide one when auth_success is True"
+ assert (
+ user_info is not None
+ ), "You must provide one when auth_success is True"
+ self.authorization_code.return_value = copy(oidc_profile)
+ self.refresh_token.return_value = copy(oidc_profile)
+ self.userinfo.return_value = copy(user_info)
else:
self.authorization_url = Mock() # type: ignore
exception = KeycloakError(
@@ -130,15 +146,19 @@
def keycloak_mock_factory(
- server_url=SERVER_URL,
- realm_name=REALM,
- client_id="swh-client-id",
- auth_success=True,
- exp=None,
+ server_url: str,
+ realm_name: str,
+ client_id: str,
+ auth_success: bool = True,
+ exp: Optional[int] = None,
user_groups=[],
user_permissions=[],
+ oidc_profile: Optional[Dict] = None,
+ user_info: Optional[Dict] = None,
+ raw_realm_public_key: Optional[str] = None,
):
- """Keycloak mock fixture factory
+ """Keycloak mock fixture factory. Report to
+ :py:class:`swh.auth.pytest_plugin.KeycloackOpenIDConnectMock` docstring.
"""
@@ -152,6 +172,9 @@
exp=exp,
user_groups=user_groups,
user_permissions=user_permissions,
+ oidc_profile=oidc_profile,
+ user_info=user_info,
+ raw_realm_public_key=raw_realm_public_key,
)
return keycloak_open_id_connect
diff --git a/swh/auth/tests/sample_data.py b/swh/auth/tests/sample_data.py
--- a/swh/auth/tests/sample_data.py
+++ b/swh/auth/tests/sample_data.py
@@ -4,7 +4,7 @@
# See top-level LICENSE file for more information
SERVER_URL = "http://keycloak:8080/keycloak/auth/"
-REALM = "SoftwareHeritage"
+REALM_NAME = "SoftwareHeritage"
CLIENT_ID = "swh-web"
# Decoded token (out of the access token)
@@ -132,11 +132,3 @@
"drX/q4E+Nzj8Tr8p7Z5CimInls40QuOTIhs6C2SwFHUgQgXl9hB9umiZJlwYEpDv0/LO2zYie"
"Hl5Lv7Iig4FOIXIVCaDGQIDAQAB"
)
-
-REALM_PUBLIC_KEY = {
- "realm": REALM,
- "public_key": RAW_REALM_PUBLIC_KEY,
- "token-service": f"{SERVER_URL}realms/{REALM}/protocol/openid-connect",
- "account-service": f"{SERVER_URL}realms/{REALM}/account",
- "tokens-not-before": 0,
-}
diff --git a/swh/auth/tests/test_keycloak.py b/swh/auth/tests/test_keycloak.py
--- a/swh/auth/tests/test_keycloak.py
+++ b/swh/auth/tests/test_keycloak.py
@@ -9,11 +9,26 @@
from keycloak.exceptions import KeycloakError
import pytest
-from swh.auth.tests.conftest import keycloak_mock_factory
-from swh.auth.tests.sample_data import CLIENT_ID, DECODED_TOKEN, OIDC_PROFILE, USER_INFO
-
-# dataset we have here is bound to swh-web
-keycloak_mock = keycloak_mock_factory(client_id=CLIENT_ID)
+from swh.auth.pytest_plugin import keycloak_mock_factory
+from swh.auth.tests.sample_data import (
+ CLIENT_ID,
+ DECODED_TOKEN,
+ OIDC_PROFILE,
+ RAW_REALM_PUBLIC_KEY,
+ REALM_NAME,
+ SERVER_URL,
+ USER_INFO,
+)
+
+# Make keycloak fixture to use for tests below.
+keycloak_mock = keycloak_mock_factory(
+ server_url=SERVER_URL,
+ realm_name=REALM_NAME,
+ client_id=CLIENT_ID,
+ oidc_profile=OIDC_PROFILE,
+ user_info=USER_INFO,
+ raw_realm_public_key=RAW_REALM_PUBLIC_KEY,
+)
def test_keycloak_well_known(keycloak_mock):
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 23, 2:50 AM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3229199
Attached To
D5194: Expose a pytest plugin for swh.auth.keycloak
Event Timeline
Log In to Comment