From 1fd8f145c00187c6a9b85b6af9f26bec10a07e87 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 3 Nov 2020 09:54:41 +0100 Subject: [PATCH 1/2] misc: set unusable password on federated users (#48136) --- src/authentic2_auth_fc/backends.py | 1 + src/authentic2_auth_oidc/backends.py | 1 + src/authentic2_auth_saml/adapters.py | 5 ++++- tests/auth_fc/test_auth_fc.py | 4 +++- tests/test_migrations.py | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/authentic2_auth_fc/backends.py b/src/authentic2_auth_fc/backends.py index 76a90a6b..9d8d4e4a 100644 --- a/src/authentic2_auth_fc/backends.py +++ b/src/authentic2_auth_fc/backends.py @@ -51,6 +51,7 @@ class FcBackend(ModelBackend): if not user and app_settings.create: User = get_user_model() user = User.objects.create(ou=get_default_ou()) + user.set_unusable_password() try: models.FcAccount.objects.create( user=user, diff --git a/src/authentic2_auth_oidc/backends.py b/src/authentic2_auth_oidc/backends.py index d3666019..7181e1c2 100644 --- a/src/authentic2_auth_oidc/backends.py +++ b/src/authentic2_auth_oidc/backends.py @@ -241,6 +241,7 @@ class OIDCBackend(ModelBackend): pass if not user: user = User.objects.create(ou=provider.ou) + user.set_unusable_password() created = True oidc_account, created = models.OIDCAccount.objects.get_or_create( provider=provider, diff --git a/src/authentic2_auth_saml/adapters.py b/src/authentic2_auth_saml/adapters.py index a5dbdbb1..87c57beb 100644 --- a/src/authentic2_auth_saml/adapters.py +++ b/src/authentic2_auth_saml/adapters.py @@ -65,7 +65,10 @@ class SamlConditionContextProxy(object): class AuthenticAdapter(DefaultAdapter): def create_user(self, user_class): - return user_class.objects.create() + user = user_class() + user.set_unusable_password() + user.save() + return user def finish_create_user(self, idp, saml_attributes, user): try: diff --git a/tests/auth_fc/test_auth_fc.py b/tests/auth_fc/test_auth_fc.py index b3da8d7d..88ac18ee 100644 --- a/tests/auth_fc/test_auth_fc.py +++ b/tests/auth_fc/test_auth_fc.py @@ -203,7 +203,9 @@ def test_requests_proxies_support(settings, app): def test_no_password_with_fc_account_can_reset_password(app, db, mailoutbox): - user = User.objects.create(email='john.doe@example.com') + user = User(email='john.doe@example.com') + user.set_unusable_password() + user.save() # No FC account, forbidden to set a password response = app.get('/login/') response = response.click('Reset it!').maybe_follow() diff --git a/tests/test_migrations.py b/tests/test_migrations.py index 86b12ff9..57ce0b44 100644 --- a/tests/test_migrations.py +++ b/tests/test_migrations.py @@ -16,6 +16,7 @@ import mock +from django.contrib.auth.models import AbstractUser from django.db.utils import ProgrammingError @@ -49,3 +50,16 @@ def test_migration_0028_trigram_unaccent_index(transactional_db, migration): with mock.patch('django.db.backends.postgresql.schema.DatabaseSchemaEditor.execute') as mocked: mocked.side_effect = programming_error migration.apply([('authentic2', '0028_trigram_unaccent_index')]) + + +def test_migration_custom_user_0021_set_unusable_password(transactional_db, migration): + old_apps = migration.before([('custom_user', '0020_deleteduser')]) + + User = old_apps.get_model('custom_user', 'User') + user = User.objects.create() + assert user.password == '' + + new_apps = migration.apply([('custom_user', '0021_set_unusable_password')]) + User = new_apps.get_model('custom_user', 'User') + user = User.objects.get() + assert not AbstractUser.has_usable_password(user) -- 2.29.1