From ae76959e50f21b0047c65e7c219bb6bafdf2e8c9 Mon Sep 17 00:00:00 2001 From: Casper van der Wel Date: Thu, 15 Feb 2024 14:56:52 +0100 Subject: [PATCH] Test with email and name from WSO2 --- nens_auth_client/backends.py | 8 ++------ nens_auth_client/cognito.py | 13 ++++++++++++- nens_auth_client/testsettings.py | 2 +- nens_auth_client/users.py | 23 +++++++++-------------- nens_auth_client/wso2.py | 6 +++++- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/nens_auth_client/backends.py b/nens_auth_client/backends.py index 38dfc63..f29f38f 100644 --- a/nens_auth_client/backends.py +++ b/nens_auth_client/backends.py @@ -1,4 +1,5 @@ from .oauth import get_oauth_client +from .users import contains_including_wildcard from .users import create_remote_user from .users import create_user from django.conf import settings @@ -7,7 +8,6 @@ from django.core.exceptions import MultipleObjectsReturned from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import PermissionDenied -from typing import Sequence import logging @@ -115,10 +115,6 @@ def authenticate(self, request, claims): return user -def contains_including_wildcard(elem: str, set_: Sequence[str]): - return "*" in set_ or elem in set_ - - class TrustedProviderMigrationBackend(ModelBackend): """Backend for users that move from cognito to a new provider, like azure @@ -160,7 +156,7 @@ def authenticate(self, request, claims): if not email: return - if contains_including_wildcard( + if not contains_including_wildcard( provider_name, settings.NENS_AUTH_TRUSTED_PROVIDERS ): logger.debug("%s not in special list of trusted providers", provider_name) diff --git a/nens_auth_client/cognito.py b/nens_auth_client/cognito.py index 221db7a..e30809b 100644 --- a/nens_auth_client/cognito.py +++ b/nens_auth_client/cognito.py @@ -149,10 +149,21 @@ def load_key(header, payload): claims.validate(leeway=leeway) return claims - def extract_provider_name(claims): + def extract_provider_name(self, claims): """Return provider name from claim and `None` if not found""" # Also used by backends.py try: return claims["identities"][0]["providerName"] except (KeyError, IndexError): return + + def extract_username(self, claims) -> str: + """Return username from claims""" + username = "" + if claims.get("identities"): + # External identity providers result in usernames that are not + # recognizable by the end user. Use the email instead. + username = claims.get("email") + if not username: + username = claims["cognito:username"] + return username diff --git a/nens_auth_client/testsettings.py b/nens_auth_client/testsettings.py index d1e4dac..5091f11 100644 --- a/nens_auth_client/testsettings.py +++ b/nens_auth_client/testsettings.py @@ -118,7 +118,7 @@ ) # Add your production name here -ALLOWED_HOSTS = ["localhost"] +ALLOWED_HOSTS = ["localhost", "0.0.0.0"] AUTHENTICATION_BACKENDS = [ "nens_auth_client.backends.RemoteUserBackend", diff --git a/nens_auth_client/users.py b/nens_auth_client/users.py index f7da571..4679806 100644 --- a/nens_auth_client/users.py +++ b/nens_auth_client/users.py @@ -15,6 +15,10 @@ User = get_user_model() +def contains_including_wildcard(elem: str, set_): + return "*" in set_ or elem in set_ + + def create_remote_user(user, claims): """Create RemoteUser to permanently associate a User with an external one. @@ -61,8 +65,6 @@ def _create_user(username, external_id): def create_user(claims): """Create User and associate it with an external one through RemoteUser. - The username is taken from the "cognito:username" field. - Raises an IntegrityError if this username already exists. This is expected to happen very rarely, in which case we do want to see this in our bug tracker. @@ -74,15 +76,9 @@ def create_user(claims): django User (created or, in case of a race condition, retrieved) RemoteUser (created or, in case of a race condition, retrieved) """ - # Format a username from the claims. - username = "" - if claims.get("identities"): - # External identity providers result in usernames that are not - # recognizable by the end user. Use the email instead. - username = claims.get("email") - if not username: - username = claims["cognito:username"] - username = username[: settings.NENS_AUTH_USERNAME_MAX_LENGTH] + username = get_oauth_client().extract_username(claims)[ + : settings.NENS_AUTH_USERNAME_MAX_LENGTH + ] external_id = claims["sub"] try: @@ -111,9 +107,8 @@ def update_user(user, claims): user.first_name = claims.get("given_name", "") user.last_name = claims.get("family_name", "") provider_name = get_oauth_client().extract_provider_name(claims) - if ( - claims.get("email_verified") - or provider_name in settings.NENS_AUTH_TRUSTED_PROVIDERS + if claims.get("email_verified") or contains_including_wildcard( + provider_name, settings.NENS_AUTH_TRUSTED_PROVIDERS ): user.email = claims.get("email", "") else: diff --git a/nens_auth_client/wso2.py b/nens_auth_client/wso2.py index bf640d9..c93614d 100644 --- a/nens_auth_client/wso2.py +++ b/nens_auth_client/wso2.py @@ -74,6 +74,10 @@ def load_key(header, payload): claims.validate(leeway=leeway) return claims - def extract_provider_name(claims): + def extract_provider_name(self, claims): """Return provider name from claim and `None` if not found""" return None + + def extract_username(self, claims) -> str: + """Return username from claims""" + return claims["email"]