# 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 . from django.contrib.auth import get_user_model from django.utils import html from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_noop import django_tables2 as tables from django_tables2.utils import A from django_rbac.utils import get_role_model, get_permission_model, \ get_ou_model from authentic2.models import Service from authentic2.middleware import StoreRequestMiddleware from authentic2_idp_oidc.models import OIDCAuthorization User = get_user_model() class PermissionLinkColumn(tables.LinkColumn): def __init__(self, viewname, **kwargs): self.permission = kwargs.pop('permission', None) super(PermissionLinkColumn, self).__init__(viewname, **kwargs) def render(self, value, record, bound_column, **kwargs): if self.permission: request = StoreRequestMiddleware.get_request() if request and not request.user.has_perm(self.permission, record): return value return super(PermissionLinkColumn, self).render(value, record, bound_column) class VerifiableEmailColumn(tables.Column): def render(self, **kwargs): user = kwargs['record'] verified = user.email_verified value = user.email if value and verified: return html.format_html( '{value}', value=value) return value class UserLinkColumn(PermissionLinkColumn): def render(self, **kwargs): user = kwargs['record'] value = super().render(**kwargs) if not user.is_active: value = html.format_html( '{value} ({disabled})', value=value, disabled=_('disabled')) return value class UserTable(tables.Table): link = UserLinkColumn( viewname='a2-manager-user-detail', permission='custom_user.view_user', verbose_name=_('User'), accessor='get_full_name', order_by=('first_name', 'last_name', 'email', 'username'), kwargs={'pk': A('pk')}) username = tables.Column() email = VerifiableEmailColumn() ou = tables.Column() class Meta: model = User attrs = {'class': 'main', 'id': 'user-table'} fields = ('username', 'email', 'first_name', 'last_name', 'ou') sequence = ('link', '...') empty_text = _('None') order_by = ('first_name', 'last_name', 'email', 'username') class RoleMembersTable(UserTable): direct = tables.BooleanColumn(verbose_name=_('Direct member'), orderable=False) via = tables.TemplateColumn( '{% for role in record.via %}' '{{ role }}{% if not forloop.last %}, {% endif %}' '{% endfor %}', verbose_name=_('Inherited from'), orderable=False) class Meta(UserTable.Meta): pass class RoleTable(tables.Table): name = tables.LinkColumn(viewname='a2-manager-role-members', kwargs={'pk': A('pk')}, accessor='name', verbose_name=_('label')) ou = tables.Column() member_count = tables.Column(verbose_name=_('Direct member count'), orderable=False) class Meta: model = get_role_model() attrs = {'class': 'main', 'id': 'role-table'} fields = ('name', 'slug', 'ou', 'member_count') class PermissionTable(tables.Table): operation = tables.Column() scope = tables.Column() target = tables.Column() class Meta: model = get_permission_model() attrs = {'class': 'main', 'id': 'role-table'} fields = ('operation', 'scope', 'target') empty_text = _('None') class OUTable(tables.Table): name = tables.Column(verbose_name=_('label')) default = tables.BooleanColumn() class Meta: model = get_ou_model() attrs = {'class': 'main', 'id': 'ou-table'} fields = ('name', 'slug', 'default') empty_text = _('None') class OuUserRolesTable(tables.Table): name = tables.LinkColumn(viewname='a2-manager-role-members', kwargs={'pk': A('pk')}, accessor='name', verbose_name=_('label')) via = tables.TemplateColumn( '''{% for rel in record.via %}{{ rel.child }} {% if not forloop.last %}, {% endif %}{% endfor %}''', verbose_name=_('Inherited from'), orderable=False) member = tables.TemplateColumn( '{%% load i18n %%}' % (ugettext_noop('You are not authorized to manage this role'), ugettext_noop('This role is synchronised from LDAP, changing members is not allowed.')), verbose_name=_('Member'), order_by=('member', 'via', 'name')) class Meta: model = get_role_model() attrs = {'class': 'main', 'id': 'role-table'} fields = ('name', 'ou') empty_text = _('None') order_by = ('name',) class UserRolesTable(tables.Table): name = tables.LinkColumn(viewname='a2-manager-role-members', kwargs={'pk': A('pk')}, accessor='name', verbose_name=_('label')) ou = tables.Column() via = tables.TemplateColumn( '{% if not record.member %}{% for rel in record.child_relation.all %}' '{{ rel.child }} {% if not forloop.last %}, {% endif %}{% endfor %}' '{% endif %}', verbose_name=_('Inherited from'), orderable=False) class Meta: model = get_role_model() attrs = {'class': 'main', 'id': 'role-table'} fields = ('name', 'ou') empty_text = _('None') order_by = ('name', 'ou') class ServiceTable(tables.Table): ou = tables.Column() name = tables.Column() slug = tables.Column() class Meta: model = Service attrs = {'class': 'main', 'id': 'service-table'} fields = ('ou', 'name', 'slug') empty_text = _('None') order_by = ('ou', 'name', 'slug') class ServiceRolesTable(tables.Table): name = tables.Column(accessor='name', verbose_name=_('name')) class Meta: model = get_role_model() attrs = {'class': 'main', 'id': 'service-role-table'} fields = ('name',) empty_text = _('No access restriction. All users are allowed to connect to this service.') class UserAuthorizationsTable(tables.Table): client = tables.Column() created = tables.Column() expired = tables.Column() class Meta: model = OIDCAuthorization attrs = {'class': 'main', 'id': 'user-authorizations-table'} fields = ('client', 'created', 'expired') empty_text = _('This user has not granted profile data access to any service yet.')