568 lines
23 KiB
Python
568 lines
23 KiB
Python
# 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/>.
|
|
|
|
import pytest
|
|
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 MANAGE_MEMBERS_OP
|
|
from authentic2.a2_rbac.models import OrganizationalUnit as OU
|
|
from authentic2.a2_rbac.models import Permission, Role, RoleAttribute
|
|
from authentic2.a2_rbac.utils import get_default_ou
|
|
from authentic2.custom_user.models import User
|
|
from authentic2.models import Service
|
|
from authentic2.utils import get_hex_uuid
|
|
from django_rbac.models import CHANGE_OP, Operation
|
|
from django_rbac.utils import get_permission_model
|
|
|
|
from .utils import login, request_select2
|
|
|
|
|
|
def test_update_rbac(db):
|
|
# 3 content types managers and 1 global manager
|
|
assert Role.objects.count() == 5
|
|
# 3 content type global permissions, 1 role administration permissions (for the main manager
|
|
# role which is self-administered)
|
|
# and 1 user view permission (for the role administrator)
|
|
# and 1 user manage authorizations permission (for the role administrator)
|
|
# and 1 ou view permission (for the user and role administrators)
|
|
assert Permission.objects.count() == 8
|
|
|
|
|
|
def test_delete_role(db):
|
|
rcount = Role.objects.count()
|
|
pcount = Permission.objects.count()
|
|
new_role = Role.objects.create(name='Coucou')
|
|
admin_role = new_role.get_admin_role()
|
|
|
|
# There should two more roles, the role and its admin counterpart
|
|
assert Role.objects.count() == rcount + 2
|
|
|
|
# There should be two more permissions the manage-members permission on the role
|
|
# and the manage-members permission on the admin role
|
|
manage_members_perm = Permission.objects.by_target(new_role).get(operation__slug='manage_members')
|
|
admin_role = Role.objects.get(
|
|
admin_scope_ct=ContentType.objects.get_for_model(manage_members_perm),
|
|
admin_scope_id=manage_members_perm.pk,
|
|
)
|
|
admin_manage_members_perm = Permission.objects.by_target(admin_role).get(operation__slug='manage_members')
|
|
assert Permission.objects.count() == pcount + 2
|
|
new_role.delete()
|
|
with pytest.raises(Permission.DoesNotExist):
|
|
Permission.objects.get(pk=manage_members_perm.pk)
|
|
with pytest.raises(Role.DoesNotExist):
|
|
Role.objects.get(pk=admin_role.pk)
|
|
with pytest.raises(Permission.DoesNotExist):
|
|
Permission.objects.get(pk=admin_manage_members_perm.pk)
|
|
assert Role.objects.count() == rcount
|
|
assert Permission.objects.count() == pcount
|
|
|
|
|
|
def test_access_control(db):
|
|
role_ct = ContentType.objects.get_for_model(Role)
|
|
role_admin_role = Role.objects.get_admin_role(role_ct, 'admin %s' % role_ct, 'admin-role')
|
|
user1 = User.objects.create(username='john.doe')
|
|
assert not user1.has_perm('a2_rbac.change_role')
|
|
assert not user1.has_perm('a2_rbac.view_role')
|
|
assert not user1.has_perm('a2_rbac.delete_role')
|
|
assert not user1.has_perm('a2_rbac.add_role')
|
|
role_admin_role.members.add(user1)
|
|
del user1._rbac_perms_cache
|
|
assert user1.has_perm('a2_rbac.change_role')
|
|
assert user1.has_perm('a2_rbac.view_role')
|
|
assert user1.has_perm('a2_rbac.delete_role')
|
|
assert user1.has_perm('a2_rbac.add_role')
|
|
|
|
|
|
def test_admin_roles_startswith_a2(db):
|
|
coin = Role.objects.create(name='Coin', slug='coin')
|
|
coin.get_admin_role()
|
|
for role in Role.objects.filter(admin_scope_ct__isnull=False):
|
|
assert role.slug.startswith('_a2'), u'role %s slug must start with _a2: %s' % (role.name, role.slug)
|
|
|
|
|
|
def test_admin_roles_update_slug(db):
|
|
user = User.objects.create(username='john.doe')
|
|
name1 = 'Can manage john.doe'
|
|
slug1 = 'can-manage-john-doe'
|
|
admin_role1 = Role.objects.get_admin_role(user, name1, slug1, update_name=True, update_slug=True)
|
|
assert admin_role1.name == name1
|
|
assert admin_role1.slug == slug1
|
|
name2 = 'Should manage john.doe'
|
|
slug2 = 'should-manage-john-doe'
|
|
admin_role2 = Role.objects.get_admin_role(user, name2, slug2, update_slug=True)
|
|
assert admin_role2.name == name1
|
|
assert admin_role2.slug == slug2
|
|
admin_role3 = Role.objects.get_admin_role(user, name2, slug2, update_name=True)
|
|
assert admin_role3.name == name2
|
|
assert admin_role3.slug == slug2
|
|
|
|
|
|
def test_role_clean(db):
|
|
coin = Role(name=u'Coin')
|
|
coin.clean()
|
|
coin.save()
|
|
assert coin.slug == 'coin'
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
Role(name='Coin2', slug='coin').full_clean()
|
|
assert 'slug' in exc_info.value.error_dict
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
Role(name='Coin', slug='coin2').full_clean()
|
|
assert 'name' in exc_info.value.error_dict
|
|
|
|
|
|
def test_role_natural_key(db):
|
|
ou = OU.objects.create(name='ou1', slug='ou1')
|
|
s1 = Service.objects.create(name='s1', slug='s1')
|
|
s2 = Service.objects.create(name='s2', slug='s2', ou=ou)
|
|
r1 = Role.objects.create(name='r1', slug='r1')
|
|
r2 = Role.objects.create(name='r2', slug='r2', ou=ou)
|
|
r3 = Role.objects.create(name='r3', slug='r3', service=s1)
|
|
r4 = Role.objects.create(name='r4', slug='r4', service=s2)
|
|
|
|
for r in (r1, r2, r3, r4):
|
|
assert Role.objects.get_by_natural_key(*r.natural_key()) == r
|
|
assert r1.natural_key() == ['r1', None, None]
|
|
assert r2.natural_key() == ['r2', ['ou1'], None]
|
|
assert r3.natural_key() == ['r3', None, [None, 's1']]
|
|
assert r4.natural_key() == ['r4', ['ou1'], [['ou1'], 's2']]
|
|
ou.delete()
|
|
with pytest.raises(Role.DoesNotExist):
|
|
Role.objects.get_by_natural_key(*r2.natural_key())
|
|
with pytest.raises(Role.DoesNotExist):
|
|
Role.objects.get_by_natural_key(*r4.natural_key())
|
|
|
|
|
|
def test_basic_role_export_json(db):
|
|
role = Role.objects.create(name='basic role', slug='basic-role', description='basic role description')
|
|
role_dict = role.export_json()
|
|
assert role_dict['name'] == role.name
|
|
assert role_dict['slug'] == role.slug
|
|
assert role_dict['uuid'] == role.uuid
|
|
assert role_dict['description'] == role.description
|
|
assert role_dict['external_id'] == role.external_id
|
|
assert role_dict['ou'] is None
|
|
assert role_dict['service'] is None
|
|
|
|
|
|
def test_role_with_ou_export_json(db):
|
|
ou = OU.objects.create(name='ou', slug='ou')
|
|
role = Role.objects.create(name='some role', ou=ou)
|
|
role_dict = role.export_json()
|
|
assert role_dict['ou'] == {'uuid': ou.uuid, 'slug': ou.slug, 'name': ou.name}
|
|
|
|
|
|
def test_role_with_service_export_json(db):
|
|
service = Service.objects.create(name='service name', slug='service-name')
|
|
role = Role.objects.create(name='some role', service=service)
|
|
role_dict = role.export_json()
|
|
assert role_dict['service'] == {'slug': service.slug, 'ou': None}
|
|
|
|
|
|
def test_role_with_service_with_ou_export_json(db):
|
|
ou = OU.objects.create(name='ou', slug='ou')
|
|
service = Service.objects.create(name='service name', slug='service-name', ou=ou)
|
|
role = Role.objects.create(name='some role', service=service)
|
|
role_dict = role.export_json()
|
|
assert role_dict['service'] == {'slug': service.slug, 'ou': {'uuid': ou.uuid, 'slug': 'ou', 'name': 'ou'}}
|
|
|
|
|
|
def test_role_with_attributes_export_json(db):
|
|
role = Role.objects.create(name='some role')
|
|
attr1 = RoleAttribute.objects.create(role=role, name='attr1_name', kind='string', value='attr1_value')
|
|
attr2 = RoleAttribute.objects.create(role=role, name='attr2_name', kind='string', value='attr2_value')
|
|
|
|
role_dict = role.export_json(attributes=True)
|
|
attributes = role_dict['attributes']
|
|
assert len(attributes) == 2
|
|
|
|
expected_attr_names = set([attr1.name, attr2.name])
|
|
for attr_dict in attributes:
|
|
assert attr_dict['name'] in expected_attr_names
|
|
expected_attr_names.remove(attr_dict['name'])
|
|
target_attr = RoleAttribute.objects.filter(name=attr_dict['name']).first()
|
|
assert attr_dict['kind'] == target_attr.kind
|
|
assert attr_dict['value'] == target_attr.value
|
|
|
|
|
|
def test_role_with_parents_export_json(db):
|
|
grand_parent_role = Role.objects.create(name='test grand parent role', slug='test-grand-parent-role')
|
|
parent_1_role = Role.objects.create(name='test parent 1 role', slug='test-parent-1-role')
|
|
parent_1_role.add_parent(grand_parent_role)
|
|
parent_2_role = Role.objects.create(name='test parent 2 role', slug='test-parent-2-role')
|
|
parent_2_role.add_parent(grand_parent_role)
|
|
child_role = Role.objects.create(name='test child role', slug='test-child-role')
|
|
child_role.add_parent(parent_1_role)
|
|
child_role.add_parent(parent_2_role)
|
|
|
|
child_role_dict = child_role.export_json(parents=True)
|
|
assert child_role_dict['slug'] == child_role.slug
|
|
parents = child_role_dict['parents']
|
|
assert len(parents) == 2
|
|
expected_slugs = set([parent_1_role.slug, parent_2_role.slug])
|
|
for parent in parents:
|
|
assert parent['slug'] in expected_slugs
|
|
expected_slugs.remove(parent['slug'])
|
|
|
|
grand_parent_role_dict = grand_parent_role.export_json(parents=True)
|
|
assert grand_parent_role_dict['slug'] == grand_parent_role.slug
|
|
assert 'parents' not in grand_parent_role_dict
|
|
|
|
parent_1_role_dict = parent_1_role.export_json(parents=True)
|
|
assert parent_1_role_dict['slug'] == parent_1_role.slug
|
|
parents = parent_1_role_dict['parents']
|
|
assert len(parents) == 1
|
|
assert parents[0]['slug'] == grand_parent_role.slug
|
|
|
|
parent_2_role_dict = parent_2_role.export_json(parents=True)
|
|
assert parent_2_role_dict['slug'] == parent_2_role.slug
|
|
parents = parent_2_role_dict['parents']
|
|
assert len(parents) == 1
|
|
assert parents[0]['slug'] == grand_parent_role.slug
|
|
|
|
|
|
def test_role_with_permission_export_json(db):
|
|
some_ou = OU.objects.create(name='some ou', slug='some-ou')
|
|
role = Role.objects.create(name='role name', slug='role-slug')
|
|
other_role = Role.objects.create(
|
|
name='other role name', slug='other-role-slug', uuid=get_hex_uuid(), ou=some_ou
|
|
)
|
|
ou = OU.objects.create(name='basic ou', slug='basic-ou', description='basic ou description')
|
|
Permission = get_permission_model()
|
|
op = Operation.objects.get(slug='add')
|
|
perm_saml = Permission.objects.create(
|
|
operation=op,
|
|
ou=ou,
|
|
target_ct=ContentType.objects.get_for_model(ContentType),
|
|
target_id=ContentType.objects.get(app_label="saml", model="libertyprovider").pk,
|
|
)
|
|
role.permissions.add(perm_saml)
|
|
perm_role = Permission.objects.create(
|
|
operation=op, ou=None, target_ct=ContentType.objects.get_for_model(Role), target_id=other_role.pk
|
|
)
|
|
role.permissions.add(perm_role)
|
|
|
|
export = role.export_json(permissions=True)
|
|
permissions = export['permissions']
|
|
assert len(permissions) == 2
|
|
assert permissions[0] == {
|
|
'operation': {'slug': 'add'},
|
|
'ou': {'uuid': ou.uuid, 'slug': ou.slug, 'name': ou.name},
|
|
'target_ct': {'app_label': u'contenttypes', 'model': u'contenttype'},
|
|
'target': {'model': u'libertyprovider', 'app_label': u'saml'},
|
|
}
|
|
assert permissions[1] == {
|
|
'operation': {'slug': 'add'},
|
|
'ou': None,
|
|
'target_ct': {'app_label': u'a2_rbac', 'model': u'role'},
|
|
'target': {
|
|
'slug': u'other-role-slug',
|
|
'service': None,
|
|
'uuid': other_role.uuid,
|
|
'ou': {'slug': u'some-ou', 'uuid': some_ou.uuid, 'name': u'some ou'},
|
|
'name': u'other role name',
|
|
},
|
|
}
|
|
|
|
|
|
def test_ou_export_json(db):
|
|
ou = OU.objects.create(
|
|
name='basic ou',
|
|
slug='basic-ou',
|
|
description='basic ou description',
|
|
username_is_unique=True,
|
|
email_is_unique=True,
|
|
default=False,
|
|
validate_emails=True,
|
|
)
|
|
ou_dict = ou.export_json()
|
|
assert ou_dict['name'] == ou.name
|
|
assert ou_dict['slug'] == ou.slug
|
|
assert ou_dict['uuid'] == ou.uuid
|
|
assert ou_dict['description'] == ou.description
|
|
assert ou_dict['username_is_unique'] == ou.username_is_unique
|
|
assert ou_dict['email_is_unique'] == ou.email_is_unique
|
|
assert ou_dict['default'] == ou.default
|
|
assert ou_dict['validate_emails'] == ou.validate_emails
|
|
|
|
|
|
def test_admin_cleanup(db):
|
|
r1 = Role.objects.create(name='r1')
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
r1.get_admin_role()
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 1
|
|
|
|
r1.delete()
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
|
|
def test_admin_cleanup_bulk_delete(db):
|
|
r1 = Role.objects.create(name='r1')
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
r1.get_admin_role()
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 1
|
|
|
|
Role.objects.filter(name='r1').delete()
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
|
|
def test_admin_cleanup_failure(db):
|
|
Role.objects.create(
|
|
name='manager of r1',
|
|
admin_scope_ct=ContentType.objects.get_for_model(Permission),
|
|
admin_scope_id=9999,
|
|
)
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 1
|
|
|
|
Role.objects.cleanup()
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
|
|
def test_admin_cleanup_command(db):
|
|
Role.objects.create(
|
|
name='manager of r1',
|
|
admin_scope_ct=ContentType.objects.get_for_model(Permission),
|
|
admin_scope_id=9999,
|
|
)
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 1
|
|
|
|
call_command('cleanupauthentic')
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
|
|
def test_role_rename(db):
|
|
r1 = Role.objects.create(name='r1')
|
|
assert r1.slug == 'r1'
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
assert not r1.get_admin_role(create=False)
|
|
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 0
|
|
|
|
ar1 = r1.get_admin_role()
|
|
|
|
assert ar1
|
|
assert ar1.name == 'Managers of role "r1"'
|
|
assert ar1.slug == '_a2-managers-of-role-r1'
|
|
assert Role.objects.filter(name__contains='r1', admin_scope_ct_id__isnull=False).count() == 1
|
|
|
|
assert ar1.name == 'Managers of role "r1"'
|
|
|
|
Role.objects.filter(pk=r1.pk).update(name='r1bis')
|
|
|
|
r1.refresh_from_db()
|
|
ar1.refresh_from_db()
|
|
|
|
assert r1.name == 'r1bis'
|
|
assert ar1.name == 'Managers of role "r1"'
|
|
|
|
ar1 = r1.get_admin_role(create=False)
|
|
|
|
assert ar1.name == 'Managers of role "r1bis"'
|
|
assert ar1.slug == '_a2-managers-of-role-r1bis'
|
|
|
|
r1.name = 'r1ter'
|
|
r1.save()
|
|
ar1.refresh_from_db()
|
|
|
|
assert ar1.name == 'Managers of role "r1ter"'
|
|
assert ar1.slug == '_a2-managers-of-role-r1ter'
|
|
|
|
|
|
def test_admin_role_user_view(db, settings, app, admin, simple_user, ou1, user_ou1, role_ou1):
|
|
role_ou1.get_admin_role().members.add(simple_user)
|
|
|
|
# Default: all users are visible
|
|
response = login(app, simple_user, '/manage/roles/')
|
|
response = response.click('role_ou1')
|
|
select2_json = request_select2(app, response)
|
|
assert select2_json['more'] is False
|
|
assert set(result['id'] for result in select2_json['results']) == set(
|
|
[simple_user.id, user_ou1.id, admin.id]
|
|
)
|
|
|
|
# with A2_RBAC_ROLE_ADMIN_RESTRICT_TO_OU_USERS after a reload of the admin
|
|
# page, we should only see user from the same OU as the role
|
|
settings.A2_RBAC_ROLE_ADMIN_RESTRICT_TO_OU_USERS = True
|
|
role_ou1.get_admin_role()
|
|
response = app.get('/manage/roles/')
|
|
response = response.click('role_ou1')
|
|
select2_json = request_select2(app, response)
|
|
assert select2_json['more'] is False
|
|
assert set(result['id'] for result in select2_json['results']) == set([user_ou1.id])
|
|
|
|
|
|
def test_no_managed_ct(transactional_db, settings):
|
|
from django.core.management.sql import emit_post_migrate_signal
|
|
|
|
call_command('flush', verbosity=0, interactive=False, database='default', reset_sequences=False)
|
|
assert Role.objects.count() == 5
|
|
OU.objects.create(name='OU1', slug='ou1')
|
|
emit_post_migrate_signal(verbosity=0, interactive=False, db='default', created_models=[])
|
|
assert Role.objects.count() == 5 + 4 + 4
|
|
settings.A2_RBAC_MANAGED_CONTENT_TYPES = ()
|
|
call_command('flush', verbosity=0, interactive=False, database='default', reset_sequences=False)
|
|
assert Role.objects.count() == 0
|
|
# create ou
|
|
OU.objects.create(name='OU1', slug='ou1')
|
|
emit_post_migrate_signal(verbosity=0, interactive=False, db='default', created_models=[])
|
|
assert Role.objects.count() == 0
|
|
|
|
|
|
def test_global_manager_roles(db):
|
|
manager = Role.objects.get(ou__isnull=True, slug='_a2-manager')
|
|
ou_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-organizational-units')
|
|
user_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-users')
|
|
role_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-roles')
|
|
service_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-services')
|
|
assert ou_manager in manager.parents()
|
|
assert user_manager in manager.parents()
|
|
assert role_manager in manager.parents()
|
|
assert service_manager in manager.parents()
|
|
assert manager.parents(include_self=False).count() == 4
|
|
assert Role.objects.count() == 5
|
|
assert OU.objects.count() == 1
|
|
|
|
|
|
def test_manager_roles_multi_ou(db, ou1):
|
|
manager = Role.objects.get(ou__isnull=True, slug='_a2-manager')
|
|
ou_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-organizational-units')
|
|
user_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-users')
|
|
role_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-roles')
|
|
service_manager = Role.objects.get(ou__isnull=True, slug='_a2-manager-of-services')
|
|
assert ou_manager in manager.parents()
|
|
assert user_manager in manager.parents()
|
|
assert role_manager in manager.parents()
|
|
assert service_manager in manager.parents()
|
|
assert manager.parents(include_self=False).count() == 4
|
|
|
|
for ou in [get_default_ou(), ou1]:
|
|
manager = Role.objects.get(ou__isnull=True, slug='_a2-managers-of-{ou.slug}'.format(ou=ou))
|
|
user_manager = Role.objects.get(ou=ou, slug='_a2-manager-of-users-{ou.slug}'.format(ou=ou))
|
|
role_manager = Role.objects.get(ou=ou, slug='_a2-manager-of-roles-{ou.slug}'.format(ou=ou))
|
|
service_manager = Role.objects.get(ou=ou, slug='_a2-manager-of-services-{ou.slug}'.format(ou=ou))
|
|
|
|
assert user_manager in manager.parents()
|
|
assert role_manager in manager.parents()
|
|
assert service_manager in manager.parents()
|
|
assert manager.parents(include_self=False).count() == 3
|
|
|
|
# 5 global roles and 4 ou roles for both ous
|
|
assert Role.objects.count() == 5 + 4 + 4
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'alert,deletion', [(-1, 31), (31, -1), (0, 31), (31, 0), (None, 31), (31, None), (32, 31)]
|
|
)
|
|
def test_unused_account_settings_validation(db, ou1, alert, deletion):
|
|
ou1.clean_unused_accounts_alert = alert
|
|
ou1.clean_unused_accounts_deletion = deletion
|
|
with pytest.raises(ValidationError):
|
|
ou1.full_clean()
|
|
|
|
|
|
def test_update_content_types_roles(transactional_db, simple_user):
|
|
from django.core.management.sql import emit_post_migrate_signal
|
|
|
|
role = Role.objects.get(name='Manager of users')
|
|
|
|
# for the purpose of this test, remove admin perm that inherit manage_authorizations perm
|
|
admin_perm = [x for x in role.permissions.all() if x.operation.name == 'Management'][0]
|
|
role.permissions.remove(admin_perm)
|
|
|
|
# 'Manager of users' role gives manage_authorizations perm
|
|
manage_authorizations_perm = [
|
|
x for x in role.permissions.all() if x.operation.name == 'Manage service consents'
|
|
][0]
|
|
assert manage_authorizations_perm
|
|
simple_user.roles.add(role)
|
|
assert simple_user.has_perm('custom_user.manage_authorizations_user')
|
|
|
|
def update_user_permissions():
|
|
del simple_user._rbac_perms_cache
|
|
simple_user.roles.add(role)
|
|
|
|
# remove manage_authorizations perm
|
|
manage_authorizations_perm.delete()
|
|
assert not [x for x in role.permissions.all() if x.operation.name == 'Manage service consents']
|
|
update_user_permissions()
|
|
assert not simple_user.has_perm('custom_user.manage_authorizations_user')
|
|
assert not [x for x in simple_user.get_all_permissions() if x == 'custom_user.manage_authorizations_user']
|
|
|
|
# manage_authorizations perm is (re-)created on post migrate
|
|
emit_post_migrate_signal(verbosity=0, interactive=False, db='default', created_models=[])
|
|
assert [x for x in role.permissions.all() if x.operation.name == 'Manage service consents'][0]
|
|
# and added to 'Manager of users' role
|
|
update_user_permissions()
|
|
assert simple_user.has_perm('custom_user.manage_authorizations_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')
|
|
OrganizationalUnit = 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()
|