From 9e52bc06c1d27ba0b4a8f188058a2139be030a7e Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 3 Dec 2020 07:49:15 +0100 Subject: [PATCH 5/5] idp_oidc: simplify oidc_client fixture (#47900) * new test test_admin will test the admin view for creating OIDCClient * default mapping are extracted in an app setting * OIDC_CLIENT_PARAMS is now only used on the main test SSO, creatint less redundant tests --- src/authentic2_idp_oidc/admin.py | 10 ++---- src/authentic2_idp_oidc/app_settings.py | 11 ++++++ tests/test_idp_oidc.py | 46 ++++++++++++++++++++----- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/authentic2_idp_oidc/admin.py b/src/authentic2_idp_oidc/admin.py index 66dc580d..4b7cfa00 100644 --- a/src/authentic2_idp_oidc/admin.py +++ b/src/authentic2_idp_oidc/admin.py @@ -21,7 +21,7 @@ from django.utils.functional import curry from authentic2.attributes_ng.engine import get_service_attributes from authentic2.forms.widgets import DatalistTextInput -from . import models +from . import models, app_settings class OIDCClaimInlineForm(forms.ModelForm): @@ -54,13 +54,7 @@ class OIDCClaimInlineAdmin(admin.TabularInline): # formsets are only saved if formset.has_changed() is True, so only set initial # values on the GET (display of the creation form) if request.method == 'GET' and not obj: - initial.extend([ - {'name': 'preferred_username', 'value': 'django_user_identifier', 'scopes': 'profile'}, - {'name': 'given_name', 'value': 'django_user_first_name', 'scopes': 'profile'}, - {'name': 'family_name', 'value': 'django_user_last_name', 'scopes': 'profile'}, - {'name': 'email', 'value': 'django_user_email', 'scopes': 'email'}, - {'name': 'email_verified', 'value': 'django_user_email_verified', 'scopes': 'email'}, - ]) + initial.extend(app_settings.DEFAULT_MAPPINGS) self.extra = 5 formset = super(OIDCClaimInlineAdmin, self).get_formset(request, obj=obj, **kwargs) formset.__init__ = curry(formset.__init__, initial=initial) diff --git a/src/authentic2_idp_oidc/app_settings.py b/src/authentic2_idp_oidc/app_settings.py index 77d1c126..80053235 100644 --- a/src/authentic2_idp_oidc/app_settings.py +++ b/src/authentic2_idp_oidc/app_settings.py @@ -65,6 +65,17 @@ class AppSettings(object): def REDIRECT_URI_MAX_LENGTH(self): return self._setting('REDIRECT_URI_MAX_LENGTH', 1024) + @property + def DEFAULT_MAPPINGS(self): + return self._setting('DEFAULT_MAPPINGS', [ + {'name': 'preferred_username', 'value': 'django_user_identifier', 'scopes': 'profile'}, + {'name': 'given_name', 'value': 'django_user_first_name', 'scopes': 'profile'}, + {'name': 'family_name', 'value': 'django_user_last_name', 'scopes': 'profile'}, + {'name': 'email', 'value': 'django_user_email', 'scopes': 'email'}, + {'name': 'email_verified', 'value': 'django_user_email_verified', 'scopes': 'email'}, + ]) + + app_settings = AppSettings('A2_IDP_OIDC_') app_settings.__name__ = __name__ sys.modules[__name__] = app_settings diff --git a/tests/test_idp_oidc.py b/tests/test_idp_oidc.py index a03c0ae5..a4377763 100644 --- a/tests/test_idp_oidc.py +++ b/tests/test_idp_oidc.py @@ -43,6 +43,7 @@ from authentic2_idp_oidc.utils import base64url from authentic2_idp_oidc.utils import get_first_rsa_sig_key from authentic2_idp_oidc.utils import get_first_ec_sig_key from authentic2_idp_oidc.utils import make_sub +from authentic2_idp_oidc import app_settings from authentic2.a2_rbac.utils import get_default_ou from authentic2.utils import make_url, good_next_url from authentic2_auth_oidc.utils import parse_timestamp @@ -135,7 +136,8 @@ OIDC_CLIENT_PARAMS = [ ] -def make_client(app, superuser, params=None): +@pytest.mark.parametrize('other_attributes', OIDC_CLIENT_PARAMS) +def test_admin(other_attributes, app, superuser, oidc_settings): Attribute.objects.create( name='cityscape_image', label='cityscape', @@ -153,12 +155,38 @@ def make_client(app, superuser, params=None): response.form.set('ou', get_default_ou().pk) response.form.set('unauthorized_url', 'https://example.com/southpark/') response.form.set('redirect_uris', 'https://example.com/callbac%C3%A9') - for key, value in (params or {}).items(): + for key, value in other_attributes.items(): response.form.set(key, value) response = response.form.submit().follow() assert OIDCClient.objects.count() == 1 - client = OIDCClient.objects.get() - utils.logout(app) + + +def make_client(app, superuser, params=None): + Attribute.objects.create( + name='cityscape_image', + label='cityscape', + kind='profile_image', + asked_on_registration=True, + required=False, + user_visible=True, + user_editable=True) + + client = OIDCClient( + name='oidcclient', + slug='oidcclient', + ou=get_default_ou(), + unauthorized_url='https://example.com/southpark/', + redirect_uris='https://example.com/callbac%C3%A9') + + for key, value in (params or {}).items(): + setattr(client, key, value) + client.save() + for mapping in app_settings.DEFAULT_MAPPINGS: + OIDCClaim.objects.create( + client=client, + name=mapping['name'], + value=mapping['value'], + scopes=mapping['scopes']) return client @@ -167,9 +195,9 @@ def client(app, superuser): return make_client(app, superuser, {}) -@pytest.fixture(params=OIDC_CLIENT_PARAMS) +@pytest.fixture def oidc_client(request, superuser, app, simple_user, oidc_settings): - return make_client(app, superuser, request.param) + return make_client(app, superuser, getattr(request, 'param', None) or {}) @pytest.fixture @@ -199,9 +227,10 @@ def bearer_authentication_headers(access_token): return {'Authorization': 'Bearer %s' % str(access_token)} +@pytest.mark.parametrize('oidc_client', OIDC_CLIENT_PARAMS, indirect=True) @pytest.mark.parametrize('do_not_ask_again', [(True,), (False,)]) @pytest.mark.parametrize('login_first', [(True,), (False,)]) -def test_authorization_code_sso(login_first, do_not_ask_again, oidc_settings, oidc_client, simple_user, app, caplog): +def test_authorization_code_sso(login_first, do_not_ask_again, oidc_client, oidc_settings, simple_user, app, caplog): redirect_uri = oidc_client.redirect_uris.split()[0] params = { 'client_id': oidc_client.client_id, @@ -450,7 +479,8 @@ def assert_authorization_response(response, fragment=False, **kwargs): assert value in location_qs[key] -def test_invalid_request(caplog, oidc_settings, oidc_client, simple_user, app): +@pytest.mark.parametrize('oidc_client', OIDC_CLIENT_PARAMS, indirect=True) +def test_invalid_request(oidc_client, caplog, oidc_settings, simple_user, app): redirect_uri = oidc_client.redirect_uris.split()[0] if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: fragment = False -- 2.29.2