diff --git a/requirements-test.txt b/requirements-test.txt --- a/requirements-test.txt +++ b/requirements-test.txt @@ -2,4 +2,5 @@ djangorestframework-stubs pytest pytest-django +pytest-mock requests_mock diff --git a/swh/auth/django/utils.py b/swh/auth/django/utils.py --- a/swh/auth/django/utils.py +++ b/swh/auth/django/utils.py @@ -6,6 +6,8 @@ from datetime import datetime, timedelta from typing import Any, Dict, Optional +from django.conf import settings + from swh.auth.django.models import OIDCUser from swh.auth.keycloak import KeycloakOpenIDConnect @@ -95,3 +97,33 @@ setattr(user, key, val) return user + + +def keycloak_oidc_client() -> KeycloakOpenIDConnect: + """ + Instantiate a KeycloakOpenIDConnect class from the following django settings: + + * KEYCLOAK_SERVER_URL + * KEYCLOAK_REALM_NAME + * KEYCLOAK_CLIENT_ID + + Returns: + An object to ease the interaction with the Keycloak server + + Raises: + ValueError: at least one mandatory django setting is not set + """ + + server_url = getattr(settings, "KEYCLOAK_SERVER_URL", None) + realm_name = getattr(settings, "KEYCLOAK_REALM_NAME", None) + client_id = getattr(settings, "KEYCLOAK_CLIENT_ID", None) + + if server_url is None or realm_name is None or client_id is None: + raise ValueError( + "KEYCLOAK_SERVER_URL, KEYCLOAK_REALM_NAME and KEYCLOAK_CLIENT_ID django " + "settings are mandatory to instantiate KeycloakOpenIDConnect class" + ) + + return KeycloakOpenIDConnect( + server_url=server_url, realm_name=realm_name, client_id=client_id + ) diff --git a/swh/auth/tests/test_utils.py b/swh/auth/tests/test_utils.py --- a/swh/auth/tests/test_utils.py +++ b/swh/auth/tests/test_utils.py @@ -6,10 +6,21 @@ from copy import copy from datetime import datetime +from django.test import override_settings import pytest -from swh.auth.django.utils import oidc_user_from_decoded_token, oidc_user_from_profile -from swh.auth.tests.sample_data import CLIENT_ID, DECODED_TOKEN, OIDC_PROFILE +from swh.auth.django.utils import ( + keycloak_oidc_client, + oidc_user_from_decoded_token, + oidc_user_from_profile, +) +from swh.auth.tests.sample_data import ( + CLIENT_ID, + DECODED_TOKEN, + OIDC_PROFILE, + REALM_NAME, + SERVER_URL, +) def test_oidc_user_from_decoded_token(): @@ -87,3 +98,24 @@ assert date_now <= user.expires_at assert isinstance(user.refresh_expires_at, datetime) assert date_now <= user.refresh_expires_at + + +def test_keycloak_oidc_client_missing_django_settings(): + + with pytest.raises(ValueError, match="settings are mandatory"): + keycloak_oidc_client() + + +@override_settings( + KEYCLOAK_SERVER_URL=SERVER_URL, + KEYCLOAK_REALM_NAME=REALM_NAME, + KEYCLOAK_CLIENT_ID=CLIENT_ID, +) +def test_keycloak_oidc_client_parameters_from_django_settings(mocker): + mocker.patch("swh.auth.keycloak.KeycloakOpenID") + + kc_oidc_client = keycloak_oidc_client() + + assert kc_oidc_client.server_url == SERVER_URL + assert kc_oidc_client.realm_name == REALM_NAME + assert kc_oidc_client.client_id == CLIENT_ID