tests: remove migration tests (#40685)
gitea/authentic/pipeline/head This commit looks good Details

Test on old migrations are useless and they will break after squashing
all migrations.
This commit is contained in:
Benjamin Dauvergne 2023-12-14 12:40:37 +01:00
parent 8cdbd3de56
commit 03a79037f5
9 changed files with 1 additions and 1222 deletions

View File

@ -733,129 +733,6 @@ def test_change_email(settings, app, franceconnect, mailoutbox, freezer):
assert User.objects.get().email == 'jane.doe@example.com'
def test_fc_authenticator_data_migration(migration, settings):
app = 'authentic2_auth_fc'
migrate_from = [(app, '0005_fcauthenticator')]
migrate_to = [(app, '0006_auto_20220525_1409')]
old_apps = migration.before(migrate_from)
FcAuthenticator = old_apps.get_model(app, 'FcAuthenticator')
settings.AUTH_FRONTENDS_KWARGS = {
'fc': {'priority': 3, 'show_condition': "'backoffice' not in login_hint"}
}
settings.A2_FC_ENABLE = True
settings.A2_FC_CLIENT_ID = '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6k'
settings.A2_FC_CLIENT_SECRET = '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6z'
settings.A2_FC_AUTHORIZE_URL = 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize'
settings.A2_FC_SCOPES = ['profile', 'email', 'birthdate']
new_apps = migration.apply(migrate_to)
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
authenticator = FcAuthenticator.objects.get()
assert authenticator.slug == 'fc-authenticator'
assert authenticator.order == 3
assert authenticator.show_condition == "'backoffice' not in login_hint"
assert authenticator.enabled is True
assert authenticator.platform == 'test'
assert authenticator.client_id == '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6k'
assert authenticator.client_secret == '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6z'
assert authenticator.scopes == ['profile', 'email', 'birthdate']
# 0007 should have no effect
new_apps = migration.apply([(app, '0007_auto_20220615_1002')])
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
assert FcAuthenticator.objects.get().pk == authenticator.pk
def test_fc_authenticator_data_migration_defaults(migration, settings):
app = 'authentic2_auth_fc'
migrate_from = [(app, '0005_fcauthenticator')]
migrate_to = [(app, '0006_auto_20220525_1409')]
old_apps = migration.before(migrate_from)
FcAuthenticator = old_apps.get_model(app, 'FcAuthenticator')
settings.A2_FC_ENABLE = False
new_apps = migration.apply(migrate_to)
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
authenticator = FcAuthenticator.objects.get()
assert authenticator.slug == 'fc-authenticator'
assert authenticator.order == -1
assert authenticator.show_condition == ''
assert authenticator.enabled is False
assert authenticator.platform == 'test'
assert authenticator.client_id == ''
assert authenticator.client_secret == ''
assert authenticator.scopes == ['profile', 'email']
def test_fc_authenticator_data_migration_empty_configuration(migration, settings):
app = 'authentic2_auth_fc'
migrate_from = [(app, '0005_fcauthenticator')]
migrate_to = [(app, '0006_auto_20220525_1409')]
old_apps = migration.before(migrate_from)
FcAuthenticator = old_apps.get_model(app, 'FcAuthenticator')
new_apps = migration.apply(migrate_to)
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
assert not FcAuthenticator.objects.exists()
def test_fc_authenticator_data_migration_bad_settings(migration, settings):
app = 'authentic2_auth_fc'
migrate_from = [(app, '0005_fcauthenticator')]
migrate_to = [(app, '0006_auto_20220525_1409')]
old_apps = migration.before(migrate_from)
FcAuthenticator = old_apps.get_model(app, 'FcAuthenticator')
settings.AUTH_FRONTENDS_KWARGS = {'fc': {'priority': None, 'show_condition': None}}
settings.A2_FC_ENABLE = False
settings.A2_FC_CLIENT_ID = 'x' * 260
settings.A2_FC_CLIENT_SECRET = None
settings.A2_FC_AUTHORIZE_URL = 'https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize'
settings.A2_FC_SCOPES = None
new_apps = migration.apply(migrate_to)
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
authenticator = FcAuthenticator.objects.get()
assert authenticator.slug == 'fc-authenticator'
assert authenticator.order == -1
assert authenticator.show_condition == ''
assert authenticator.enabled is False
assert authenticator.platform == 'test'
assert authenticator.client_id == 'x' * 256
assert authenticator.client_secret == ''
assert authenticator.scopes == ['profile', 'email']
def test_fc_authenticator_data_migration_fixup(migration, settings):
app = 'authentic2_auth_fc'
migrate_from = [(app, '0006_auto_20220525_1409')]
migrate_to = [(app, '0007_auto_20220615_1002')]
old_apps = migration.before(migrate_from)
FcAuthenticator = old_apps.get_model(app, 'FcAuthenticator')
# authenticator was not created by 0006
assert not FcAuthenticator.objects.exists()
settings.A2_FC_ENABLE = True
settings.A2_FC_CLIENT_ID = '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6k'
settings.A2_FC_CLIENT_SECRET = '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6z'
new_apps = migration.apply(migrate_to)
FcAuthenticator = new_apps.get_model(app, 'FcAuthenticator')
# authenticator was created by 0007
authenticator = FcAuthenticator.objects.get()
assert authenticator.slug == 'fc-authenticator'
assert authenticator.client_id == '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6k'
def test_bad_email_handling(settings, app, franceconnect, caplog):
caplog.set_level(logging.WARNING)

View File

@ -1,43 +0,0 @@
# authentic2 - authentic2 authentication for FranceConnect
# Copyright (C) 2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
def test_migration_0003_0004_fcaccount_order(migration):
migrate_from = [('authentic2_auth_fc', '0002_auto_20200416_1439')]
# it's a two-parts migration, as it contains data and schema changes.
migrate_to = [('authentic2_auth_fc', '0004_fcaccount_order2')]
old_apps = migration.before(migrate_from, at_end=False)
User = old_apps.get_model('custom_user', 'User')
FcAccount = old_apps.get_model('authentic2_auth_fc', 'FcAccount')
user1 = User.objects.create(username='user1')
user2 = User.objects.create(username='user2')
user3 = User.objects.create(username='user3')
FcAccount.objects.create(user=user1, sub='sub1')
FcAccount.objects.create(user=user1, sub='sub2')
FcAccount.objects.create(user=user2, sub='sub2')
FcAccount.objects.create(user=user2, sub='sub3')
FcAccount.objects.create(user=user3, sub='sub3')
assert len(set(FcAccount.objects.values_list('user_id', flat=True))) == 3
assert len(set(FcAccount.objects.values_list('sub', flat=True))) == 3
assert FcAccount.objects.count() == 5
# execute migration
new_apps = migration.apply(migrate_to)
FcAccount = new_apps.get_model('authentic2_auth_fc', 'FcAccount')
assert len(set(FcAccount.objects.values_list('user_id', 'order'))) == 5
assert len(set(FcAccount.objects.values_list('sub', 'order'))) == 5

View File

@ -1308,78 +1308,6 @@ def test_auth_time_is_null(app, caplog, code, oidc_provider, oidc_provider_jwkse
assert User.objects.count() == 1
@pytest.mark.parametrize(
'auth_frontend_kwargs',
[
{'oidc': {'priority': 3, 'show_condition': '"backoffice" not in login_hint'}},
{'oidc': {'show_condition': {'baz': '"backoffice" not in login_hint', 'bar': 'True'}}},
],
)
def test_oidc_provider_authenticator_data_migration(auth_frontend_kwargs, migration, settings):
settings.AUTH_FRONTENDS_KWARGS = auth_frontend_kwargs
app = 'authentic2_auth_oidc'
migrate_from = [(app, '0008_auto_20201102_1142')]
migrate_to = [(app, '0012_auto_20220524_1147')]
old_apps = migration.before(migrate_from)
OIDCProvider = old_apps.get_model(app, 'OIDCProvider')
OIDCClaimMapping = old_apps.get_model(app, 'OIDCClaimMapping')
OIDCAccount = old_apps.get_model(app, 'OIDCAccount')
OrganizationalUnit = old_apps.get_model('a2_rbac', 'OrganizationalUnit')
User = old_apps.get_model('custom_user', 'User')
ou1 = OrganizationalUnit.objects.create(name='OU1', slug='ou1')
issuer = 'https://baz.example.com'
first_provider = OIDCProvider.objects.create(
name='Baz',
slug='baz',
ou=ou1,
show=True,
issuer=issuer,
authorization_endpoint='%s/authorize' % issuer,
token_endpoint='%s/token' % issuer,
end_session_endpoint='%s/logout' % issuer,
userinfo_endpoint='%s/user_info' % issuer,
token_revocation_endpoint='%s/revoke' % issuer,
)
second_provider = OIDCProvider.objects.create(name='Second', slug='second', ou=ou1)
second_provider_claim_mapping = OIDCClaimMapping.objects.create(
provider=second_provider, claim='second_provider', attribute='username'
)
user1 = User.objects.create()
second_provider_account = OIDCAccount.objects.create(
user=user1, provider=second_provider, sub='second_provider'
)
first_provider_claim_mapping = OIDCClaimMapping.objects.create(
provider=first_provider, claim='first_provider', attribute='username'
)
new_apps = migration.apply(migrate_to)
OIDCProvider = new_apps.get_model(app, 'OIDCProvider')
BaseAuthenticator = new_apps.get_model('authenticators', 'BaseAuthenticator')
authenticator = OIDCProvider.objects.get(slug='baz')
assert authenticator.name == 'Baz'
assert authenticator.ou.pk == ou1.pk
assert authenticator.enabled is True
assert authenticator.order == auth_frontend_kwargs['oidc'].get('priority', 2)
assert authenticator.show_condition == '"backoffice" not in login_hint'
assert authenticator.authorization_endpoint == '%s/authorize' % issuer
assert authenticator.claim_mappings.count() == 1
assert authenticator.claim_mappings.get().pk == first_provider_claim_mapping.pk
assert not authenticator.accounts.exists()
base_authenticator = BaseAuthenticator.objects.get(slug='baz')
assert authenticator.uuid == base_authenticator.uuid
second_authenticator = OIDCProvider.objects.get(slug='second')
assert second_authenticator.name == 'Second'
assert second_authenticator.claim_mappings.count() == 1
assert second_authenticator.claim_mappings.get().pk == second_provider_claim_mapping.pk
assert second_authenticator.accounts.count() == 1
assert second_authenticator.accounts.get().pk == second_provider_account.pk
def test_only_idtoken_claims(app, caplog, code, oidc_provider, oidc_provider_jwkset):
oidc_provider.claim_mappings.update(idtoken_claim=True)
response = app.get('/').maybe_follow()

View File

@ -125,39 +125,6 @@ class TestAddRole:
assert role_random not in user.roles.all()
def test_addroleaction_migration(role_random, migration):
SAMLAuthenticator.objects.create(
enabled=True,
metadata='meta1.xml',
slug='idp1',
)
old_apps = migration.before([('authenticators', '0016_alter_addroleaction_condition')])
AddRoleAction = old_apps.get_model('authenticators', 'AddRoleAction')
BaseAuthenticator = old_apps.get_model('authenticators', 'BaseAuthenticator')
Role = old_apps.get_model('a2_rbac', 'Role')
base_authenticator = BaseAuthenticator.objects.get(slug='idp1')
role = Role.objects.get(slug=role_random.slug)
ara = AddRoleAction.objects.create(
authenticator=base_authenticator, role=role, attribute_name='groups', attribute_value='Test'
)
ara_nocondition = AddRoleAction.objects.create(authenticator=base_authenticator, role=role)
new_apps = migration.apply([('authenticators', '0017_auto_20230927_1517')]) # buggy migration
AddRoleAction = new_apps.get_model('authenticators', 'AddRoleAction')
ara = AddRoleAction.objects.get(id=ara.id)
ara_nocondition = AddRoleAction.objects.get(id=ara_nocondition.id)
assert ara.condition == 'attributes.groups in "Test"'
assert ara_nocondition.condition == 'attributes. in ""' # buggy condition
new_apps = migration.apply([('authenticators', '0019_fix_addroleaction_condition')])
AddRoleAction = new_apps.get_model('authenticators', 'AddRoleAction')
ara = AddRoleAction.objects.get(id=ara.id)
ara_nocondition = AddRoleAction.objects.get(id=ara_nocondition.id)
assert ara.condition == 'attributes.groups in "Test"'
assert ara_nocondition.condition == '' # fixed
def test_apply_attribute_mapping_missing_attribute_exception(
adapter, idp, saml_attributes, title_attribute, user, rf
):

View File

@ -1,428 +0,0 @@
# authentic2 - versatile identity manager
# Copyright (C) 2010-2022 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
def test_saml_authenticator_data_migration(migration, settings):
app = 'authentic2_auth_saml'
migrate_from = [(app, '0001_initial')]
migrate_to = [(app, '0002_auto_20220608_1559')]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model(app, 'SAMLAuthenticator')
settings.A2_AUTH_SAML_ENABLE = True
settings.MELLON_METADATA_CACHE_TIME = 42
settings.MELLON_METADATA_HTTP_TIMEOUT = 42
settings.MELLON_PROVISION = False
settings.MELLON_VERIFY_SSL_CERTIFICATE = True
settings.MELLON_TRANSIENT_FEDERATION_ATTRIBUTE = None
settings.MELLON_USERNAME_TEMPLATE = 'test'
settings.MELLON_NAME_ID_POLICY_ALLOW_CREATE = False
settings.MELLON_FORCE_AUTHN = True
settings.MELLON_ADD_AUTHNREQUEST_NEXT_URL_EXTENSION = False
settings.MELLON_GROUP_ATTRIBUTE = 'role'
settings.MELLON_CREATE_GROUP = True
settings.MELLON_ERROR_URL = 'https://example.com/error/'
settings.MELLON_AUTHN_CLASSREF = ('class1', 'class2')
settings.MELLON_LOGIN_HINTS = ['hint1', 'hint2']
settings.AUTH_FRONTENDS_KWARGS = {
'saml': {
'priority': 1,
'show_condition': {
'0': 'first condition',
'1': 'second condition',
},
}
}
settings.MELLON_IDENTITY_PROVIDERS = [
{
'METADATA': os.path.join(os.path.dirname(__file__), 'metadata.xml'),
'REALM': 'test',
'METADATA_CACHE_TIME': 43,
'METADATA_HTTP_TIMEOUT': 43,
'PROVISION': True,
'LOOKUP_BY_ATTRIBUTES': [],
},
{
'METADATA_PATH': os.path.join(os.path.dirname(__file__), 'metadata.xml'),
'NAME_ID_POLICY_ALLOW_CREATE': True,
'FORCE_AUTHN': False,
'ADD_AUTHNREQUEST_NEXT_URL_EXTENSION': True,
'A2_ATTRIBUTE_MAPPING': [
{
'attribute': 'email',
'saml_attribute': 'mail',
},
],
'LOOKUP_BY_ATTRIBUTES': [{'saml_attribute': 'email', 'user_field': 'email'}],
},
{
'METADATA_URL': 'https://example.com/metadata.xml',
'SLUG': 'third',
'ATTRIBUTE_MAPPING': {'email': 'attributes[mail][0]'},
'SUPERUSER_MAPPING': {'roles': 'Admin'},
},
]
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model(app, 'SAMLAuthenticator')
first_authenticator, second_authenticator, third_authenticator = SAMLAuthenticator.objects.all()
assert first_authenticator.slug == '0'
assert first_authenticator.order == 1
assert first_authenticator.show_condition == 'first condition'
assert first_authenticator.enabled is True
assert first_authenticator.metadata_path == os.path.join(os.path.dirname(__file__), 'metadata.xml')
assert first_authenticator.metadata_url == ''
assert first_authenticator.metadata_cache_time == 43
assert first_authenticator.metadata_http_timeout == 43
assert first_authenticator.provision is True
assert first_authenticator.verify_ssl_certificate is True
assert first_authenticator.transient_federation_attribute == ''
assert first_authenticator.realm == 'test'
assert first_authenticator.username_template == 'test'
assert first_authenticator.name_id_policy_format == ''
assert first_authenticator.name_id_policy_allow_create is False
assert first_authenticator.force_authn is True
assert first_authenticator.add_authnrequest_next_url_extension is False
assert first_authenticator.group_attribute == 'role'
assert first_authenticator.create_group is True
assert first_authenticator.error_url == 'https://example.com/error/'
assert first_authenticator.error_redirect_after_timeout == 120
assert first_authenticator.authn_classref == 'class1, class2'
assert first_authenticator.login_hints == 'hint1, hint2'
assert first_authenticator.lookup_by_attributes == []
assert first_authenticator.a2_attribute_mapping == []
assert first_authenticator.attribute_mapping == {}
assert first_authenticator.superuser_mapping == {}
assert second_authenticator.slug == '1'
assert second_authenticator.order == 1
assert second_authenticator.show_condition == 'second condition'
assert second_authenticator.enabled is True
assert second_authenticator.metadata_path == os.path.join(os.path.dirname(__file__), 'metadata.xml')
assert second_authenticator.metadata_url == ''
assert second_authenticator.metadata_cache_time == 42
assert second_authenticator.metadata_http_timeout == 42
assert second_authenticator.provision is False
assert second_authenticator.verify_ssl_certificate is True
assert second_authenticator.transient_federation_attribute == ''
assert second_authenticator.realm == 'saml'
assert second_authenticator.username_template == 'test'
assert second_authenticator.name_id_policy_format == ''
assert second_authenticator.name_id_policy_allow_create is True
assert second_authenticator.force_authn is False
assert second_authenticator.add_authnrequest_next_url_extension is True
assert second_authenticator.group_attribute == 'role'
assert second_authenticator.create_group is True
assert second_authenticator.error_url == 'https://example.com/error/'
assert second_authenticator.error_redirect_after_timeout == 120
assert second_authenticator.authn_classref == 'class1, class2'
assert second_authenticator.login_hints == 'hint1, hint2'
assert second_authenticator.lookup_by_attributes == [{'saml_attribute': 'email', 'user_field': 'email'}]
assert second_authenticator.a2_attribute_mapping == [
{
'attribute': 'email',
'saml_attribute': 'mail',
},
]
assert first_authenticator.attribute_mapping == {}
assert first_authenticator.superuser_mapping == {}
assert third_authenticator.slug == 'third'
assert third_authenticator.order == 1
assert third_authenticator.show_condition == ''
assert third_authenticator.enabled is True
assert third_authenticator.metadata_path == ''
assert third_authenticator.metadata_url == 'https://example.com/metadata.xml'
assert third_authenticator.metadata_cache_time == 42
assert third_authenticator.metadata_http_timeout == 42
assert third_authenticator.provision is False
assert third_authenticator.verify_ssl_certificate is True
assert third_authenticator.transient_federation_attribute == ''
assert third_authenticator.realm == 'saml'
assert third_authenticator.username_template == 'test'
assert third_authenticator.name_id_policy_format == ''
assert third_authenticator.name_id_policy_format == ''
assert third_authenticator.name_id_policy_allow_create is False
assert third_authenticator.force_authn is True
assert third_authenticator.group_attribute == 'role'
assert third_authenticator.create_group is True
assert third_authenticator.error_url == 'https://example.com/error/'
assert third_authenticator.error_redirect_after_timeout == 120
assert third_authenticator.authn_classref == 'class1, class2'
assert third_authenticator.login_hints == 'hint1, hint2'
assert third_authenticator.lookup_by_attributes == [
{'saml_attribute': 'email', 'user_field': 'email', 'ignore-case': True},
{'saml_attribute': 'username', 'user_field': 'username'},
]
assert third_authenticator.a2_attribute_mapping == []
assert third_authenticator.attribute_mapping == {'email': 'attributes[mail][0]'}
assert third_authenticator.superuser_mapping == {'roles': 'Admin'}
def test_saml_authenticator_data_migration_empty_configuration(migration, settings):
app = 'authentic2_auth_saml'
migrate_from = [(app, '0001_initial')]
migrate_to = [(app, '0002_auto_20220608_1559')]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model(app, 'SAMLAuthenticator')
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model(app, 'SAMLAuthenticator')
assert not SAMLAuthenticator.objects.exists()
def test_saml_authenticator_data_migration_bad_settings(migration, settings):
app = 'authentic2_auth_saml'
migrate_from = [(app, '0001_initial')]
migrate_to = [(app, '0002_auto_20220608_1559')]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model(app, 'SAMLAuthenticator')
settings.AUTH_FRONTENDS_KWARGS = {'saml': {'priority': None, 'show_condition': None}}
settings.MELLON_METADATA_CACHE_TIME = 2**16
settings.MELLON_METADATA_HTTP_TIMEOUT = -1
settings.MELLON_PROVISION = None
settings.MELLON_USERNAME_TEMPLATE = 42
settings.MELLON_GROUP_ATTRIBUTE = None
settings.MELLON_ERROR_URL = 'a' * 500
settings.MELLON_AUTHN_CLASSREF = 'not-a-list'
settings.MELLON_IDENTITY_PROVIDERS = [
{
'METADATA': os.path.join(os.path.dirname(__file__), 'metadata.xml'),
'ERROR_REDIRECT_AFTER_TIMEOUT': -1,
'SUPERUSER_MAPPING': 'not-a-dict',
},
]
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model(app, 'SAMLAuthenticator')
authenticator = SAMLAuthenticator.objects.get()
assert authenticator.slug == '0'
assert authenticator.order == 3
assert authenticator.show_condition == ''
assert authenticator.enabled is False
assert authenticator.metadata_cache_time == 3600
assert authenticator.metadata_http_timeout == 10
assert authenticator.provision is True
assert authenticator.username_template == '{attributes[name_id_content]}@{realm}'
assert authenticator.group_attribute == ''
assert authenticator.error_url == 'a' * 200
assert authenticator.error_redirect_after_timeout == 120
assert authenticator.authn_classref == ''
assert authenticator.superuser_mapping == {}
def test_saml_authenticator_data_migration_json_fields(migration, settings):
migrate_from = [
(
'authentic2_auth_saml',
'0005_addroleaction_renameattributeaction_samlattributelookup_setattributeaction',
),
('a2_rbac', '0036_delete_roleattribute'),
]
migrate_to = [
('authentic2_auth_saml', '0006_migrate_jsonfields'),
('a2_rbac', '0036_delete_roleattribute'),
]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
Role = old_apps.get_model('a2_rbac', 'Role')
OU = old_apps.get_model('a2_rbac', 'OrganizationalUnit')
ou = OU.objects.create(name='Test OU', slug='test-ou')
role = Role.objects.create(name='Test role', slug='test-role', ou=ou)
SAMLAuthenticator.objects.create(
metadata='meta1.xml',
slug='idp1',
lookup_by_attributes=[
{'saml_attribute': 'email', 'user_field': 'email'},
{'saml_attribute': 'saml_name', 'user_field': 'first_name', 'ignore-case': True},
],
a2_attribute_mapping=[
{
'attribute': 'email',
'saml_attribute': 'mail',
'mandatory': True,
},
{'action': 'rename', 'from': 'a' * 1025, 'to': 'first_name'},
{
'attribute': 'first_name',
'saml_attribute': 'first_name',
},
{
'attribute': 'invalid',
'saml_attribute': '',
},
{
'attribute': 'invalid',
'saml_attribute': None,
},
{
'attribute': 'invalid',
},
{
'action': 'add-role',
'role': {
'name': role.name,
'ou': {
'name': role.ou.name,
},
},
'condition': "roles == 'A'",
},
],
)
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
authenticator = SAMLAuthenticator.objects.get()
attribute_lookup1, attribute_lookup2 = authenticator.attribute_lookups.all().order_by('pk')
assert attribute_lookup1.saml_attribute == 'email'
assert attribute_lookup1.user_field == 'email'
assert attribute_lookup1.ignore_case is False
assert attribute_lookup2.saml_attribute == 'saml_name'
assert attribute_lookup2.user_field == 'first_name'
assert attribute_lookup2.ignore_case is True
set_attribute1, set_attribute2 = authenticator.set_attribute_actions.all().order_by('pk')
assert set_attribute1.attribute == 'email'
assert set_attribute1.saml_attribute == 'mail'
assert set_attribute1.mandatory is True
assert set_attribute2.attribute == 'first_name'
assert set_attribute2.saml_attribute == 'first_name'
assert set_attribute2.mandatory is False
rename_attribute = authenticator.rename_attribute_actions.get()
assert rename_attribute.from_name == 'a' * 1024
assert rename_attribute.to_name == 'first_name'
add_role = authenticator.add_role_actions.get()
assert add_role.role.pk == role.pk
assert add_role.condition == "roles == 'A'"
assert add_role.mandatory is False
def test_saml_authenticator_data_migration_json_fields_log_errors(migration, settings, caplog):
migrate_from = [
(
'authentic2_auth_saml',
'0005_addroleaction_renameattributeaction_samlattributelookup_setattributeaction',
),
('a2_rbac', '0036_delete_roleattribute'),
]
migrate_to = [
('authentic2_auth_saml', '0006_migrate_jsonfields'),
('a2_rbac', '0036_delete_roleattribute'),
]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
SAMLAuthenticator.objects.create(
metadata='meta1.xml',
slug='idp1',
lookup_by_attributes=[{'saml_attribute': 'email', 'user_field': 'email'}],
a2_attribute_mapping=['bad'],
)
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
authenticator = SAMLAuthenticator.objects.get()
assert not authenticator.attribute_lookups.exists()
assert caplog.messages == [
'could not create related objects for authenticator SAMLAuthenticator object (%s)' % authenticator.pk,
'attribute mapping for SAMLAuthenticator object (%s): ["bad"]' % authenticator.pk,
'lookup by attributes for SAMLAuthenticator object (%s): [{"user_field": "email", "saml_attribute": "email"}]'
% authenticator.pk,
]
def test_saml_authenticator_data_migration_rename_attributes(migration, settings):
migrate_from = [('authentic2_auth_saml', '0008_auto_20220913_1105')]
migrate_to = [('authentic2_auth_saml', '0009_statically_rename_attributes')]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
RenameAttributeAction = old_apps.get_model('authentic2_auth_saml', 'RenameAttributeAction')
SetAttributeAction = old_apps.get_model('authentic2_auth_saml', 'SetAttributeAction')
SAMLAttributeLookup = old_apps.get_model('authentic2_auth_saml', 'SAMLAttributeLookup')
authenticator = SAMLAuthenticator.objects.create(slug='idp1')
RenameAttributeAction.objects.create(
authenticator=authenticator, from_name='http://nice/attribute/givenName', to_name='first_name'
)
SAMLAttributeLookup.objects.create(
authenticator=authenticator, user_field='first_name', saml_attribute='first_name'
)
SAMLAttributeLookup.objects.create(
authenticator=authenticator, user_field='title', saml_attribute='title'
)
SetAttributeAction.objects.create(
authenticator=authenticator, user_field='first_name', saml_attribute='first_name'
)
SetAttributeAction.objects.create(authenticator=authenticator, user_field='title', saml_attribute='title')
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
authenticator = SAMLAuthenticator.objects.get()
attribute_lookup1, attribute_lookup2 = authenticator.attribute_lookups.all().order_by('pk')
assert attribute_lookup1.saml_attribute == 'http://nice/attribute/givenName'
assert attribute_lookup1.user_field == 'first_name'
assert attribute_lookup2.saml_attribute == 'title'
assert attribute_lookup2.user_field == 'title'
set_attribute1, set_attribute2 = authenticator.set_attribute_actions.all().order_by('pk')
assert set_attribute1.saml_attribute == 'http://nice/attribute/givenName'
assert set_attribute1.user_field == 'first_name'
assert set_attribute2.saml_attribute == 'title'
assert set_attribute2.user_field == 'title'
def test_saml_authenticator_data_migration_metadata_file_to_db(migration, settings):
migrate_from = [('authentic2_auth_saml', '0012_move_add_role_action')]
migrate_to = [('authentic2_auth_saml', '0014_remove_samlauthenticator_metadata_path')]
old_apps = migration.before(migrate_from)
SAMLAuthenticator = old_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
SAMLAuthenticator.objects.create(
slug='idp1', metadata_path=os.path.join(os.path.dirname(__file__), 'metadata.xml')
)
SAMLAuthenticator.objects.create(slug='idp2', metadata='xxx')
SAMLAuthenticator.objects.create(slug='idp3', metadata_url='https://example.com')
SAMLAuthenticator.objects.create(slug='idp4', metadata_path='/unknown/')
new_apps = migration.apply(migrate_to)
SAMLAuthenticator = new_apps.get_model('authentic2_auth_saml', 'SAMLAuthenticator')
authenticator = SAMLAuthenticator.objects.get(slug='idp1')
assert authenticator.metadata.startswith('<?xml version="1.0"?>')
assert authenticator.metadata.endswith('</EntityDescriptor>\n')
assert SAMLAuthenticator.objects.filter(slug='idp2', metadata='xxx').count() == 1
assert SAMLAuthenticator.objects.filter(slug='idp3', metadata_url='https://example.com').count() == 1

View File

@ -1,125 +0,0 @@
# authentic2 - versatile identity manager
# Copyright (C) 2010-2021 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
def test_oidclient_claims_data_migration(migration):
app = 'authentic2_idp_oidc'
migrate_from = [(app, '0009_auto_20180313_1156')]
migrate_to = [(app, '0010_oidcclaim')]
old_apps = migration.before(migrate_from)
OIDCClient = old_apps.get_model('authentic2_idp_oidc', 'OIDCClient')
client = OIDCClient(name='test', slug='test', redirect_uris='https://example.net/')
client.save()
new_apps = migration.apply(migrate_to)
OIDCClient = new_apps.get_model('authentic2_idp_oidc', 'OIDCClient')
OIDCClaim = new_apps.get_model('authentic2_idp_oidc', 'OIDCClaim')
client = OIDCClient.objects.first()
assert OIDCClaim.objects.filter(client=client.id).count() == 5
def test_oidclient_preferred_username_as_identifier_data_migration(migration):
app = 'authentic2_idp_oidc'
migrate_from = [(app, '0010_oidcclaim')]
migrate_to = [(app, '0011_auto_20180808_1546')]
old_apps = migration.before(migrate_from)
OIDCClient = old_apps.get_model('authentic2_idp_oidc', 'OIDCClient')
OIDCClaim = old_apps.get_model('authentic2_idp_oidc', 'OIDCClaim')
client1 = OIDCClient.objects.create(name='test', slug='test', redirect_uris='https://example.net/')
client2 = OIDCClient.objects.create(name='test1', slug='test1', redirect_uris='https://example.net/')
client3 = OIDCClient.objects.create(name='test2', slug='test2', redirect_uris='https://example.net/')
client4 = OIDCClient.objects.create(name='test3', slug='test3', redirect_uris='https://example.net/')
for client in (client1, client2, client3, client4):
if client.name == 'test1':
continue
if client.name == 'test3':
OIDCClaim.objects.create(
client=client, name='preferred_username', value='django_user_full_name', scopes='profile'
)
else:
OIDCClaim.objects.create(
client=client, name='preferred_username', value='django_user_username', scopes='profile'
)
OIDCClaim.objects.create(
client=client, name='given_name', value='django_user_first_name', scopes='profile'
)
OIDCClaim.objects.create(
client=client, name='family_name', value='django_user_last_name', scopes='profile'
)
if client.name == 'test2':
continue
OIDCClaim.objects.create(client=client, name='email', value='django_user_email', scopes='email')
OIDCClaim.objects.create(
client=client, name='email_verified', value='django_user_email_verified', scopes='email'
)
new_apps = migration.apply(migrate_to)
OIDCClient = new_apps.get_model('authentic2_idp_oidc', 'OIDCClient')
client = OIDCClient.objects.first()
for client in OIDCClient.objects.all():
claims = client.oidcclaim_set.all()
if client.name == 'test':
assert claims.count() == 5
assert sorted(claims.values_list('name', flat=True)) == [
'email',
'email_verified',
'family_name',
'given_name',
'preferred_username',
]
assert sorted(claims.values_list('value', flat=True)) == [
'django_user_email',
'django_user_email_verified',
'django_user_first_name',
'django_user_identifier',
'django_user_last_name',
]
elif client.name == 'test2':
assert claims.count() == 3
assert sorted(claims.values_list('name', flat=True)) == [
'family_name',
'given_name',
'preferred_username',
]
assert sorted(claims.values_list('value', flat=True)) == [
'django_user_first_name',
'django_user_last_name',
'django_user_username',
]
elif client.name == 'test3':
assert claims.count() == 5
assert sorted(claims.values_list('name', flat=True)) == [
'email',
'email_verified',
'family_name',
'given_name',
'preferred_username',
]
assert sorted(claims.values_list('value', flat=True)) == [
'django_user_email',
'django_user_email_verified',
'django_user_first_name',
'django_user_full_name',
'django_user_last_name',
]
else:
assert claims.count() == 0

View File

@ -19,7 +19,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.management import call_command
from authentic2.a2_rbac.models import CHANGE_OP, MANAGE_MEMBERS_OP, Operation
from authentic2.a2_rbac.models import CHANGE_OP, Operation
from authentic2.a2_rbac.models import OrganizationalUnit as OU
from authentic2.a2_rbac.models import Permission, Role
from authentic2.a2_rbac.utils import get_default_ou
@ -542,48 +542,6 @@ def test_update_content_types_roles(transactional_db, simple_user):
assert [x for x in simple_user.get_all_permissions() if x == 'custom_user.manage_authorizations_user']
@pytest.mark.parametrize('new_perm_exists', [True, False])
def test_update_self_admin_perm_migration(migration, new_perm_exists):
old_apps = migration.before([('a2_rbac', '0022_auto_20200402_1101')])
Role = old_apps.get_model('a2_rbac', 'Role')
old_apps.get_model('a2_rbac', 'OrganizationalUnit')
Permission = old_apps.get_model('a2_rbac', 'Permission')
Operation = old_apps.get_model('django_rbac', 'Operation')
ContentType = old_apps.get_model('contenttypes', 'ContentType')
ct = ContentType.objects.get_for_model(Role)
change_op, _ = Operation.objects.get_or_create(slug=CHANGE_OP.slug)
manage_members_op, _ = Operation.objects.get_or_create(slug=MANAGE_MEMBERS_OP.slug)
# add old self administration
role = Role.objects.create(name='name', slug='slug')
self_perm, _ = Permission.objects.get_or_create(operation=change_op, target_ct=ct, target_id=role.pk)
role.permissions.add(self_perm)
if new_perm_exists:
new_self_perm, _ = Permission.objects.get_or_create(
operation=manage_members_op, target_ct=ct, target_id=role.pk
)
else:
Permission.objects.filter(operation=manage_members_op, target_ct=ct, target_id=role.pk).delete()
new_apps = migration.apply([('a2_rbac', '0024_fix_self_admin_perm')])
Role = new_apps.get_model('a2_rbac', 'Role')
Operation = old_apps.get_model('django_rbac', 'Operation')
role = Role.objects.get(slug='slug')
assert role.permissions.count() == 1
perm = role.permissions.first()
assert perm.operation.pk == manage_members_op.pk
assert perm.target_ct.pk == ct.pk
assert perm.target_id == role.pk
if new_perm_exists:
assert perm.pk == new_self_perm.pk
assert not Permission.objects.filter(operation=change_op, target_ct=ct, target_id=role.pk).exists()
class TestRole:
@scoped_db_fixture(scope='class')
def fixture(self):
@ -707,118 +665,3 @@ class TestRole:
def test_direct(self, db, fixture):
assert set(fixture.role.children(direct=True)) == {fixture.role, fixture.child}
assert fixture.role.children(include_self=False, direct=True).get() == fixture.child
def test_a2_rbac_operation_migration(migration, settings):
migrate_from = [
('a2_rbac', '0030_organizationalunit_min_password_strength'),
('django_rbac', '0009_auto_20221004_1343'),
]
migrate_to = [('a2_rbac', '0033_remove_old_operation_fk')]
old_apps = migration.before(migrate_from)
ContentType = old_apps.get_model('contenttypes', 'ContentType')
Operation = old_apps.get_model('django_rbac', 'Operation')
Permission = old_apps.get_model('a2_rbac', 'Permission')
# check objects created by signal handlers
base_operation = Operation.objects.get(slug='view')
base_permission = Permission.objects.filter(operation=base_operation).first()
# check other objects
new_operation = Operation.objects.create(slug='test')
Permission.objects.create(
operation=new_operation,
target_ct=ContentType.objects.get_for_model(ContentType),
target_id=ContentType.objects.get_for_model(User).pk,
)
new_apps = migration.apply(migrate_to)
ContentType = new_apps.get_model('contenttypes', 'ContentType')
Operation = new_apps.get_model('a2_rbac', 'Operation')
Permission = new_apps.get_model('a2_rbac', 'Permission')
base_operation = Operation.objects.get(slug='view')
assert (
Permission.objects.filter(
operation_id=base_operation,
target_ct_id=base_permission.target_ct.pk,
target_id=base_permission.target_id,
).count()
== 1
)
new_operation = Operation.objects.get(slug=new_operation.slug)
assert (
Permission.objects.filter(
operation=new_operation,
target_ct=ContentType.objects.get_for_model(ContentType),
target_id=ContentType.objects.get_for_model(User).pk,
).count()
== 1
)
def test_a2_rbac_role_attribute_migration(migration, settings):
migrate_from = [('a2_rbac', '0034_new_role_fields')]
migrate_to = [('a2_rbac', '0036_delete_roleattribute')]
old_apps = migration.before(migrate_from)
Role = old_apps.get_model('a2_rbac', 'Role')
RoleAttribute = old_apps.get_model('a2_rbac', 'RoleAttribute')
role = Role.objects.create(name='role', slug='1')
RoleAttribute.objects.create(role=role, kind='json', name='details', value='"abc"')
RoleAttribute.objects.create(role=role, kind='json', name='emails', value='["a@a.com", "b@b.com"]')
RoleAttribute.objects.create(role=role, kind='json', name='emails_to_members', value='false')
RoleAttribute.objects.create(role=role, kind='string', name='is_superuser', value='true')
role = Role.objects.create(name='role_default_values', slug='2')
RoleAttribute.objects.create(role=role, kind='json', name='details', value='""')
RoleAttribute.objects.create(role=role, kind='json', name='emails', value='[]')
RoleAttribute.objects.create(role=role, kind='json', name='emails_to_members', value='true')
RoleAttribute.objects.create(role=role, kind='string', name='is_superuser', value='false')
role = Role.objects.create(name='role_no_attribute', slug='3')
role = Role.objects.create(name='role_bad_attributes', slug='4')
RoleAttribute.objects.create(role=role, kind='json', name='details', value='bad')
RoleAttribute.objects.create(role=role, kind='json', name='emails', value='true')
RoleAttribute.objects.create(role=role, kind='json', name='emails_to_members', value='bad')
RoleAttribute.objects.create(role=role, kind='string', name='unknown', value='xxx')
role = Role.objects.create(name='role_one_attribute', slug='5')
RoleAttribute.objects.create(role=role, kind='json', name='details', value='"xxx"')
new_apps = migration.apply(migrate_to)
Role = new_apps.get_model('a2_rbac', 'Role')
role = Role.objects.get(name='role')
assert role.details == 'abc'
assert role.emails == ['a@a.com', 'b@b.com']
assert role.emails_to_members is False
assert role.is_superuser is True
role = Role.objects.get(name='role_default_values')
assert role.details == ''
assert role.emails == []
assert role.emails_to_members is True
assert role.is_superuser is False
role = Role.objects.get(name='role_no_attribute')
assert role.details == ''
assert role.emails == []
assert role.emails_to_members is True
assert role.is_superuser is False
role = Role.objects.get(name='role_bad_attributes')
assert role.details == ''
assert role.emails == []
assert role.emails_to_members is True
assert role.is_superuser is False
role = Role.objects.get(name='role_one_attribute')
assert role.details == 'xxx'
assert role.emails == []
assert role.emails_to_members is True
assert role.is_superuser is False

View File

@ -602,157 +602,3 @@ def test_button_description(app, db):
response = app.get('/login/')
assert 'This is a test.' in response.text
def test_password_authenticator_data_migration(migration, settings):
app = 'authenticators'
migrate_from = [(app, '0002_loginpasswordauthenticator')]
migrate_to = [(app, '0003_auto_20220413_1504')]
old_apps = migration.before(migrate_from)
LoginPasswordAuthenticator = old_apps.get_model(app, 'LoginPasswordAuthenticator')
settings.AUTH_FRONTENDS_KWARGS = {
'password': {'priority': -1, 'show_condition': "'backoffice' not in login_hint"}
}
settings.A2_LOGIN_FORM_OU_SELECTOR = True
settings.A2_AUTH_PASSWORD_ENABLE = False
settings.A2_USER_REMEMBER_ME = 42
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.slug == 'password-authenticator'
assert authenticator.order == -1
assert authenticator.show_condition == "'backoffice' not in login_hint"
assert authenticator.enabled is False
assert authenticator.remember_me == 42
assert authenticator.include_ou_selector is True
def test_password_authenticator_data_migration_new_settings(migration, settings):
app = 'authenticators'
migrate_from = [(app, '0008_new_password_settings_fields')]
migrate_to = [(app, '0009_migrate_new_password_settings')]
old_apps = migration.before(migrate_from)
LoginPasswordAuthenticator = old_apps.get_model(app, 'LoginPasswordAuthenticator')
settings.A2_PASSWORD_POLICY_MIN_LENGTH = 10
settings.A2_PASSWORD_POLICY_REGEX = '^.*ok.*$'
settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG = 'not ok'
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_DURATION = 10.5
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_FACTOR = 1
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_MAX_DURATION = 100
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_MIN_DURATION = 200
settings.A2_EMAILS_IP_RATELIMIT = '42/h'
settings.A2_SMS_IP_RATELIMIT = '43/h'
settings.A2_EMAILS_ADDRESS_RATELIMIT = '44/h'
settings.A2_SMS_NUMBER_RATELIMIT = '45/h'
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.password_min_length == 10
assert authenticator.password_regex == '^.*ok.*$'
assert authenticator.password_regex_error_msg == 'not ok'
assert authenticator.login_exponential_retry_timeout_duration == 10.5
assert authenticator.login_exponential_retry_timeout_factor == 1
assert authenticator.login_exponential_retry_timeout_max_duration == 100
assert authenticator.login_exponential_retry_timeout_min_duration == 200
assert authenticator.emails_ip_ratelimit == '42/h'
assert authenticator.sms_ip_ratelimit == '43/h'
assert authenticator.emails_address_ratelimit == '44/h'
assert authenticator.sms_number_ratelimit == '45/h'
def test_password_authenticator_data_migration_new_settings_invalid(migration, settings):
app = 'authenticators'
migrate_from = [(app, '0008_new_password_settings_fields')]
migrate_to = [(app, '0009_migrate_new_password_settings')]
old_apps = migration.before(migrate_from)
LoginPasswordAuthenticator = old_apps.get_model(app, 'LoginPasswordAuthenticator')
settings.A2_PASSWORD_POLICY_MIN_LENGTH = 'abc'
settings.A2_PASSWORD_POLICY_REGEX = None
settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG = 42
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_DURATION = None
settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_MAX_DURATION = 10.5
settings.A2_EMAILS_IP_RATELIMIT = None
settings.A2_SMS_IP_RATELIMIT = 42
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.password_min_length == 8
assert authenticator.password_regex == ''
assert authenticator.password_regex_error_msg == ''
assert authenticator.login_exponential_retry_timeout_duration == 1
assert authenticator.login_exponential_retry_timeout_max_duration == 10
assert authenticator.emails_ip_ratelimit == '10/h'
assert authenticator.sms_ip_ratelimit == '10/h'
@pytest.mark.parametrize('email,phone', [(True, True), (True, False), (False, True)])
def test_password_authenticator_migration_accept_authentication_settings(migration, settings, email, phone):
app = 'authenticators'
migrate_from = [(app, '0010_auto_20230614_1017')]
migrate_to = [(app, '0011_migrate_a2_accept_authentication_settings')]
migration.before(migrate_from)
settings.A2_ACCEPT_EMAIL_AUTHENTICATION = email
settings.A2_ACCEPT_PHONE_AUTHENTICATION = phone
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.accept_email_authentication == email
assert authenticator.accept_phone_authentication == phone
@pytest.mark.parametrize('strength,expected_strength', [(None, 3), ('invalid', 3), (1, 3), (4, 4), (42, 4)])
def test_password_authenticator_data_migration_min_password_strength(
migration, settings, strength, expected_strength
):
app = 'authenticators'
migrate_from = [
(app, '0012_loginpasswordauthenticator_min_password_strength'),
('a2_rbac', '0036_delete_roleattribute'),
]
migrate_to = [(app, '0013_migrate_min_password_strength')]
old_apps = migration.before(migrate_from)
OU = old_apps.get_model('a2_rbac', 'OrganizationalUnit')
settings.A2_PASSWORD_POLICY_MIN_STRENGTH = strength
OU.objects.create(name='OU1', slug='ou1', min_password_strength=2)
OU.objects.create(name='OU2', slug='ou2', min_password_strength=None)
OU.objects.create(name='OU3', slug='ou3', min_password_strength=3)
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.min_password_strength == expected_strength
def test_password_authenticator_data_migration_min_password_strength_zero(migration, settings):
app = 'authenticators'
migrate_from = [
(app, '0012_loginpasswordauthenticator_min_password_strength'),
('a2_rbac', '0036_delete_roleattribute'),
]
migrate_to = [(app, '0013_migrate_min_password_strength')]
old_apps = migration.before(migrate_from)
OU = old_apps.get_model('a2_rbac', 'OrganizationalUnit')
OU.objects.create(name='OU1', slug='ou1', min_password_strength=0)
new_apps = migration.apply(migrate_to)
LoginPasswordAuthenticator = new_apps.get_model(app, 'LoginPasswordAuthenticator')
authenticator = LoginPasswordAuthenticator.objects.get()
assert authenticator.min_password_strength == 0

View File

@ -1,86 +0,0 @@
# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib.auth.models import AbstractUser
from django.utils.timezone import now
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)
def test_migration_custom_user_0026_remove_user_deleted(transactional_db, migration):
old_apps = migration.before([('custom_user', '0025_user_deactivation')])
User = old_apps.get_model('custom_user', 'User')
DeletedUser = old_apps.get_model('custom_user', 'DeletedUser')
User.objects.create(deleted=now())
User.objects.create()
assert User.objects.count() == 2
assert DeletedUser.objects.count() == 0
new_apps = migration.apply([('custom_user', '0026_remove_user_deleted')])
User = new_apps.get_model('custom_user', 'User')
DeletedUser = new_apps.get_model('custom_user', 'DeletedUser')
assert User.objects.count() == 1
assert DeletedUser.objects.count() == 1
def test_migration_custom_user_0028_user_email_verified_date(transactional_db, migration):
old_apps = migration.before([('custom_user', '0027_user_deactivation_reason')])
User = old_apps.get_model('custom_user', 'User')
User.objects.create(email='john.doe@example.com', email_verified=True)
new_apps = migration.apply([('custom_user', '0028_user_email_verified_date')])
User = new_apps.get_model('custom_user', 'User')
user = User.objects.get()
assert user.email_verified_date == user.date_joined
def test_migration_custom_user_0047_initialize_services_runtime_settings(transactional_db, migration):
old_apps = migration.before([('authentic2', '0046_runtimesetting')])
Setting = old_apps.get_model('authentic2', 'Setting')
assert Setting.objects.count() == 0
new_apps = migration.apply([('authentic2', '0047_initialize_services_runtime_settings')])
Setting = new_apps.get_model('authentic2', 'Setting')
assert Setting.objects.count() == 4
assert Setting.objects.filter(key__startswith='sso:').count() == 4
for setting in Setting.objects.filter(key__startswith='sso:'):
assert setting.value == ''
def test_migration_custom_user_0050_initialize_users_advanced_configuration(transactional_db, migration):
old_apps = migration.before([('authentic2', '0049_apiclient_allowed_user_attributes')])
Setting = old_apps.get_model('authentic2', 'Setting')
before = Setting.objects.count()
new_apps = migration.apply([('authentic2', '0050_initialize_users_advanced_configuration')])
Setting = new_apps.get_model('authentic2', 'Setting')
assert Setting.objects.count() == before + 1
assert Setting.objects.filter(key__startswith='users:').count() == 1
assert Setting.objects.get(key='users:backoffice_sidebar_template').value == ''