Page MenuHomeSoftware Heritage

D5194.id18585.diff
No OneTemporary

D5194.id18585.diff

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

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

Event Timeline