0001-a2_rbac-do-not-break-unicity-when-get-or-creating-ad.patch
src/authentic2/a2_rbac/management.py | ||
---|---|---|
138 | 138 |
continue |
139 | 139 |
ct_admin_role = Role.objects.get_admin_role(instance=ct, name=name, |
140 | 140 |
slug=slug, |
141 |
update_name=True) |
|
141 |
update_name=True, |
|
142 |
update_slug=True, |
|
143 |
create=True) |
|
142 | 144 |
if MANAGED_CT[ct_tuple].get('must_view_user'): |
143 | 145 |
ct_admin_role.permissions.add(view_user_perm) |
144 | 146 |
ct_admin_role.permissions.add(search_ou_perm) |
... | ... | |
153 | 155 |
administered_role = old_perm.target |
154 | 156 |
admin_role = administered_role.get_admin_role() |
155 | 157 |
new_perm = admin_role.permissions.get(operation__slug=MANAGE_MEMBERS_OP.slug) |
158 |
assert new_perm.ou is None |
|
156 | 159 |
admin_role.delete() |
157 | 160 |
role.admin_scope_id = new_perm.pk |
158 |
role.save() |
|
161 |
role.save(update_fields=['admin_scope_id'])
|
|
159 | 162 |
role.permissions.remove(old_perm) |
160 | 163 |
role.permissions.add(new_perm) |
161 |
assert role.pk == administered_role.get_admin_role().pk |
|
164 |
assert role.pk == administered_role.get_admin_role(create=False).pk |
src/authentic2/a2_rbac/managers.py | ||
---|---|---|
41 | 41 |
op = get_operation(operation) |
42 | 42 |
Permission = rbac_utils.get_permission_model() |
43 | 43 |
if create: |
44 |
perm, created = Permission.objects.get_or_create(
|
|
44 |
perm, _ = Permission.objects.get_or_create(
|
|
45 | 45 |
operation=op, |
46 | 46 |
target_ct=ContentType.objects.get_for_model(instance), |
47 | 47 |
target_id=instance.pk, |
... | ... | |
55 | 55 |
**kwargs) |
56 | 56 |
except Permission.DoesNotExist: |
57 | 57 |
return None |
58 |
created = False |
|
59 | 58 | |
60 | 59 |
admin_role = self.get_mirror_role(perm, name, slug, ou=ou, |
61 | 60 |
update_name=update_name, |
... | ... | |
76 | 75 | |
77 | 76 |
def get_mirror_role(self, instance, name, slug, ou=None, |
78 | 77 |
update_name=False, update_slug=False, create=True): |
79 |
'''Get or create a role which mirror another model, for example a |
|
78 |
'''Get or create a role which mirrors another model, for example a
|
|
80 | 79 |
permission. |
81 | 80 |
''' |
82 | 81 |
ct = ContentType.objects.get_for_model(instance) |
82 |
update_fields = {} |
|
83 | 83 |
kwargs = {} |
84 |
if ou or getattr(instance, 'ou', None): |
|
85 |
kwargs['ou'] = ou or instance.ou |
|
84 |
ou = ou or getattr(instance, 'ou', None) |
|
85 |
if ou: |
|
86 |
update_fields['ou'] = ou |
|
86 | 87 |
else: |
87 | 88 |
kwargs['ou__isnull'] = True |
89 |
if update_name: |
|
90 |
update_fields['name'] = name |
|
91 |
if update_slug: |
|
92 |
update_fields['slug'] = slug |
|
93 | ||
88 | 94 |
if create: |
89 |
role, created = self.prefetch_related('permissions').get_or_create(
|
|
95 |
role, _ = self.prefetch_related('permissions').update_or_create(
|
|
90 | 96 |
admin_scope_ct=ct, |
91 | 97 |
admin_scope_id=instance.pk, |
92 |
defaults={ |
|
93 |
'name': name, |
|
94 |
'slug': slug, |
|
95 |
}, |
|
98 |
defaults=update_fields, |
|
96 | 99 |
**kwargs) |
97 | 100 |
else: |
98 | 101 |
try: |
... | ... | |
102 | 105 |
**kwargs) |
103 | 106 |
except self.model.DoesNotExist: |
104 | 107 |
return None |
105 |
created = False |
|
106 | ||
107 |
if update_name and not created and role.name != name: |
|
108 |
role.name = name |
|
109 |
role.save() |
|
110 |
if update_slug and not created and role.slug != slug: |
|
111 |
role.slug = slug |
|
112 |
role.save() |
|
108 |
for field, value in update_fields.items(): |
|
109 |
setattr(role, field, value) |
|
110 |
role.save(update_fields=update_fields) |
|
113 | 111 |
return role |
114 | 112 | |
115 | 113 |
def get_by_natural_key(self, slug, ou_natural_key, service_natural_key): |
src/authentic2/a2_rbac/models.py | ||
---|---|---|
151 | 151 |
slug = '_a2-managers-of-{ou.slug}'.format(ou=self) |
152 | 152 |
return Role.objects.get_admin_role( |
153 | 153 |
instance=self, name=name, slug=slug, operation=VIEW_OP, |
154 |
update_name=True, update_slug=True) |
|
154 |
update_name=True, update_slug=True, create=True)
|
|
155 | 155 | |
156 | 156 |
def delete(self, *args, **kwargs): |
157 | 157 |
Permission.objects.filter(ou=self).delete() |
tests/test_a2_rbac.py | ||
---|---|---|
108 | 108 |
user = User.objects.create(username='john.doe') |
109 | 109 |
name1 = 'Can manage john.doe' |
110 | 110 |
slug1 = 'can-manage-john-doe' |
111 |
admin_role1 = Role.objects.get_admin_role(user, name1, slug1) |
|
111 |
admin_role1 = Role.objects.get_admin_role(user, name1, slug1, update_name=True, update_slug=True)
|
|
112 | 112 |
assert admin_role1.name == name1 |
113 | 113 |
assert admin_role1.slug == slug1 |
114 | 114 |
name2 = 'Should manage john.doe' |
... | ... | |
403 | 403 |
assert ar1.slug == '_a2-managers-of-role-r1ter' |
404 | 404 | |
405 | 405 | |
406 |
def test_admin_role_user_view(settings, app, admin, simple_user, ou1, user_ou1, role_ou1): |
|
406 |
def test_admin_role_user_view(db, settings, app, admin, simple_user, ou1, user_ou1, role_ou1):
|
|
407 | 407 |
role_ou1.get_admin_role().members.add(simple_user) |
408 | 408 | |
409 | 409 |
# Default: all users are visible |
... | ... | |
493 | 493 |
@pytest.mark.parametrize( |
494 | 494 |
'alert,deletion', [(-1, 31), (31, -1), (0, 31), (31, 0), (None, 31), (31, None), (32, 31)] |
495 | 495 |
) |
496 |
def test_unused_account_settings_validation(ou1, alert, deletion): |
|
496 |
def test_unused_account_settings_validation(db, ou1, alert, deletion):
|
|
497 | 497 |
ou1.clean_unused_accounts_alert = alert |
498 | 498 |
ou1.clean_unused_accounts_deletion = deletion |
499 | 499 |
with pytest.raises(ValidationError): |
500 |
- |