diff --git a/CHANGES b/CHANGES index d2d13a01..a53051c3 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,10 @@ Thanks to plumdog Thanks to plumdog +UNRELEASED +---------- +- Allowed creating Users with multiple required fields. + 0.17.1 (2018-07-16) ---------- - A 403 (permission denied) is now raised if a SAMLResponse is replayed, instead of 500. diff --git a/djangosaml2/backends.py b/djangosaml2/backends.py index bea054d6..f461f3b5 100644 --- a/djangosaml2/backends.py +++ b/djangosaml2/backends.py @@ -147,19 +147,21 @@ def _get_or_create_saml2_user(self, main_attribute, attributes, attribute_mappin main_attribute) django_user_main_attribute = self.get_django_user_main_attribute() user_query_args = self.get_user_query_args(main_attribute) - user_create_defaults = {django_user_main_attribute: main_attribute} User = get_saml_user_model() + built = False try: - user, created = User.objects.get_or_create( - defaults=user_create_defaults, **user_query_args) + user = User.objects.get(**user_query_args) + except User.DoesNotExist: + user = User(**{django_user_main_attribute: main_attribute}) + built = True except MultipleObjectsReturned: logger.error("There are more than one user with %s = %s", django_user_main_attribute, main_attribute) return None - if created: - logger.debug('New user created') + if built: + logger.debug('Configuring new user "%s"', main_attribute) user = self.configure_user(user, attributes, attribute_mapping) else: logger.debug('User updated') diff --git a/tests/testprofiles/models.py b/tests/testprofiles/models.py index 767da2ae..2d01591f 100644 --- a/tests/testprofiles/models.py +++ b/tests/testprofiles/models.py @@ -30,3 +30,13 @@ class StandaloneUserModel(models.Model): USERNAME_FIELD. """ username = models.CharField(max_length=30, unique=True) + + +class RequiredFieldUser(models.Model): + email = models.EmailField(unique=True) + email_verified = models.BooleanField() + + USERNAME_FIELD = 'email' + + def set_unusable_password(self): + pass diff --git a/tests/testprofiles/tests.py b/tests/testprofiles/tests.py index 073bea80..a648f4d6 100644 --- a/tests/testprofiles/tests.py +++ b/tests/testprofiles/tests.py @@ -134,6 +134,26 @@ def test_invalid_model_attribute_log(self): logs.output, ) + @override_settings(AUTH_USER_MODEL='testprofiles.RequiredFieldUser') + def test_create_user_with_required_fields(self): + backend = Saml2Backend() + attribute_mapping = { + 'mail': ['email'], + 'mail_verified': ['email_verified'] + } + attributes = { + 'mail': ['john@example.org'], + 'mail_verified': [True], + } + # User creation does not fail if several fields are required. + user = backend._get_or_create_saml2_user( + 'john@example.org', + attributes, + attribute_mapping, + ) + self.assertEquals(user.email, 'john@example.org') + self.assertIs(user.email_verified, True) + def test_django_user_main_attribute(self): backend = Saml2Backend()