a2_rbac: set admin role view permissions to role's OU users (#84706)
gitea/authentic/pipeline/head This commit looks good
Details
gitea/authentic/pipeline/head This commit looks good
Details
This commit is contained in:
parent
dc5b825cd8
commit
4ba169c4c1
|
@ -20,7 +20,6 @@ import sys
|
|||
class AppSettings:
|
||||
__DEFAULTS = dict(
|
||||
MANAGED_CONTENT_TYPES=None,
|
||||
ROLE_ADMIN_RESTRICT_TO_OU_USERS=False,
|
||||
)
|
||||
|
||||
def __init__(self, prefix):
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# Generated by Django 3.2.18 on 2024-01-25 10:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def update_admin_roles_permissions(apps, schema_editor):
|
||||
Operation = apps.get_model('a2_rbac', 'Operation')
|
||||
try:
|
||||
view_operation = Operation.objects.get(slug='view')
|
||||
except Operation.DoesNotExist:
|
||||
return
|
||||
|
||||
OrganizationalUnit = apps.get_model('a2_rbac', 'OrganizationalUnit')
|
||||
Permission = apps.get_model('a2_rbac', 'Permission')
|
||||
User = apps.get_model('custom_user', 'User')
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
|
||||
target_ct = ContentType.objects.get_for_model(ContentType)
|
||||
target_id = ContentType.objects.get_for_model(User).pk
|
||||
user_view_permission_qs = Permission.objects.filter(
|
||||
operation=view_operation, target_ct=target_ct, target_id=target_id
|
||||
)
|
||||
global_user_view_permission = user_view_permission_qs.get(ou__isnull=True)
|
||||
for ou in OrganizationalUnit.objects.exclude(default=True):
|
||||
try:
|
||||
ou_user_view_permission = user_view_permission_qs.get(ou=ou)
|
||||
except Permission.DoesNotExist:
|
||||
continue
|
||||
# admin roles start with _
|
||||
for r in ou.role_set.filter(slug__startswith='_'):
|
||||
if ou_user_view_permission not in r.permissions.all():
|
||||
continue
|
||||
r.permissions.remove(global_user_view_permission)
|
||||
r.permissions.add(ou_user_view_permission)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('a2_rbac', '0038_organizationalunit_phone_is_unique'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(update_admin_roles_permissions, reverse_code=migrations.RunPython.noop)
|
||||
]
|
|
@ -39,7 +39,7 @@ from authentic2.decorators import errorcollector
|
|||
from authentic2.utils.cache import GlobalCache
|
||||
from authentic2.validators import HexaColourValidator
|
||||
|
||||
from . import app_settings, fields, managers, utils
|
||||
from . import fields, managers, utils
|
||||
|
||||
|
||||
class AbstractBase(models.Model):
|
||||
|
@ -448,11 +448,7 @@ class Role(AbstractBase):
|
|||
def get_admin_role(self, create=True):
|
||||
from . import utils
|
||||
|
||||
if app_settings.ROLE_ADMIN_RESTRICT_TO_OU_USERS:
|
||||
view_user_perm = utils.get_view_user_perm(ou=self.ou)
|
||||
else:
|
||||
view_user_perm = utils.get_view_user_perm()
|
||||
|
||||
view_user_perm = utils.get_view_user_perm(ou=self.ou)
|
||||
admin_role = self.__class__.objects.get_admin_role(
|
||||
self,
|
||||
name=_('Managers of role "{role}"').format(role=str(self)),
|
||||
|
|
|
@ -109,6 +109,22 @@ def test_admin_roles_update_slug(db):
|
|||
assert admin_role3.slug == slug2
|
||||
|
||||
|
||||
def test_role_view_user_perm_on_ou_update(db):
|
||||
role = Role.objects.create(name='Admin')
|
||||
admin_role = role.get_admin_role()
|
||||
assert admin_role.permissions.get(operation__slug='view').ou is None
|
||||
|
||||
default_ou = get_default_ou()
|
||||
role.ou = default_ou
|
||||
role.save()
|
||||
assert admin_role.permissions.get(operation__slug='view').ou == default_ou
|
||||
|
||||
new_ou = OU.objects.create(name='New OU')
|
||||
role.ou = new_ou
|
||||
role.save()
|
||||
assert admin_role.permissions.get(operation__slug='view').ou == new_ou
|
||||
|
||||
|
||||
def test_role_clean(db):
|
||||
coin = Role(name='Coin')
|
||||
coin.clean()
|
||||
|
@ -392,24 +408,20 @@ def test_role_rename(db):
|
|||
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
|
||||
# Default: only OU 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
|
||||
user_ids = {int(x['id'].split('-')[1]) for x in select2_json['results'] if x['id'].startswith('user')}
|
||||
assert user_ids == {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
|
||||
user_ids = {int(x['id'].split('-')[1]) for x in select2_json['results'] if x['id'].startswith('user')}
|
||||
assert user_ids == {user_ou1.id}
|
||||
# add user to OU
|
||||
admin.ou = ou1
|
||||
admin.save()
|
||||
select2_json = request_select2(app, response)
|
||||
user_ids = {int(x['id'].split('-')[1]) for x in select2_json['results'] if x['id'].startswith('user')}
|
||||
# it must be visible
|
||||
assert user_ids == {user_ou1.id, admin.id}
|
||||
|
||||
|
||||
def test_no_managed_ct(transactional_db, settings):
|
||||
|
|
Loading…
Reference in New Issue