authentic/src/authentic2/a2_rbac/management.py

145 lines
5.5 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/>.
from django.contrib.contenttypes.models import ContentType
from django.utils import six
from django.utils.text import slugify
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from django_rbac.models import ADMIN_OP
from django_rbac.utils import get_ou_model, get_permission_model, get_role_model
from ..utils import get_fk_model
from . import app_settings, utils
from .models import MANAGE_MEMBERS_OP
def update_ou_admin_roles(ou):
Role = get_role_model()
if app_settings.MANAGED_CONTENT_TYPES == ():
Role.objects.filter(slug='a2-managers-of-{ou.slug}'.format(ou=ou)).delete()
else:
ou_admin_role = ou.get_admin_role()
for key in MANAGED_CT:
ct = ContentType.objects.get_by_natural_key(key[0], key[1])
model_class = ct.model_class()
ou_model = get_fk_model(model_class, 'ou')
# do not create scoped admin roles if the model is not scopable
if not ou_model:
continue
name = six.text_type(MANAGED_CT[key]['name'])
slug = '_a2-' + slugify(name)
scoped_name = six.text_type(MANAGED_CT[key]['scoped_name'])
name = scoped_name.format(ou=ou)
ou_slug = slug + '-' + ou.slug
if app_settings.MANAGED_CONTENT_TYPES == ():
Role.objects.filter(slug=ou_slug, ou=ou).delete()
continue
else:
ou_ct_admin_role = Role.objects.get_admin_role(
instance=ct, ou=ou, name=name, slug=ou_slug, update_slug=True, update_name=True
)
if not app_settings.MANAGED_CONTENT_TYPES or key in app_settings.MANAGED_CONTENT_TYPES:
ou_ct_admin_role.add_child(ou_admin_role)
else:
ou_ct_admin_role.remove_child(ou_admin_role)
if MANAGED_CT[key].get('must_view_user'):
ou_ct_admin_role.permissions.add(utils.get_view_user_perm(ou))
ou_ct_admin_role.permissions.add(utils.get_search_ou_perm(ou))
def update_ous_admin_roles():
"""Create general admin roles linked to all organizational units,
they give general administrative rights to all mamanged content types
scoped to the given organizational unit.
"""
OU = get_ou_model()
ou_all = OU.objects.all()
if len(ou_all) < 2:
# If there is no ou or less than two, only generate global management
# roles
return
for ou in ou_all:
update_ou_admin_roles(ou)
MANAGED_CT = {
('a2_rbac', 'role'): {
'name': _('Manager of roles'),
'scoped_name': _('Roles - {ou}'),
'must_view_user': True,
},
('a2_rbac', 'organizationalunit'): {
'name': _('Manager of organizational units'),
'scoped_name': _('Organizational unit - {ou}'),
},
('custom_user', 'user'): {
'name': _('Manager of users'),
'scoped_name': _('Users - {ou}'),
'must_manage_authorizations_user': True,
},
('authentic2', 'service'): {
'name': _('Manager of services'),
'scoped_name': _('Services - {ou}'),
},
}
def update_content_types_roles():
"""Create general and scoped management roles for all managed content
types.
"""
cts = ContentType.objects.all()
Role = get_role_model()
view_user_perm = utils.get_view_user_perm()
search_ou_perm = utils.get_search_ou_perm()
manage_authorizations_user_perm = utils.get_manage_authorizations_user_perm()
slug = '_a2-manager'
if app_settings.MANAGED_CONTENT_TYPES == ():
Role.objects.filter(slug=slug).delete()
else:
admin_role, created = Role.objects.get_or_create(slug=slug, defaults=dict(name=ugettext('Manager')))
admin_role.add_self_administration()
if not created and admin_role.name != ugettext('Manager'):
admin_role.name = ugettext('Manager')
admin_role.save()
for ct in cts:
ct_tuple = (ct.app_label.lower(), ct.model.lower())
if ct_tuple not in MANAGED_CT:
continue
# General admin role
name = six.text_type(MANAGED_CT[ct_tuple]['name'])
slug = '_a2-' + slugify(name)
if (
app_settings.MANAGED_CONTENT_TYPES is not None
and ct_tuple not in app_settings.MANAGED_CONTENT_TYPES
):
Role.objects.filter(slug=slug).delete()
continue
ct_admin_role = Role.objects.get_admin_role(
instance=ct, name=name, slug=slug, update_name=True, update_slug=True, create=True
)
if MANAGED_CT[ct_tuple].get('must_view_user'):
ct_admin_role.permissions.add(view_user_perm)
if MANAGED_CT[ct_tuple].get('must_manage_authorizations_user'):
ct_admin_role.permissions.add(manage_authorizations_user_perm)
ct_admin_role.permissions.add(search_ou_perm)
ct_admin_role.add_child(admin_role)