manager: show indirect members of roles real roles (#44927)

This commit is contained in:
Benjamin Dauvergne 2020-07-12 09:28:12 +02:00
parent c429e7bffb
commit 4ede4af066
4 changed files with 41 additions and 5 deletions

View File

@ -23,7 +23,7 @@ from django.views.generic import FormView, TemplateView
from django.views.generic.detail import SingleObjectMixin
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.db.models.query import Q
from django.db.models.query import Q, Prefetch
from django.db.models import Count
from django.contrib.auth import get_user_model
@ -158,7 +158,9 @@ class RoleMembersView(views.HideOUColumnMixin, RoleViewMixin, views.BaseSubTable
self._can_manage_members = value
def get_table_queryset(self):
return self.object.all_members()
children = self.object.children(include_self=False)
via_prefetch = Prefetch('roles', queryset=children, to_attr='via')
return self.object.all_members().prefetch_related(via_prefetch)
def form_valid(self, form):
user = form.cleaned_data['user']

View File

@ -68,6 +68,11 @@ class UserTable(tables.Table):
class RoleMembersTable(UserTable):
direct = tables.BooleanColumn(verbose_name=_('Direct member'),
orderable=False)
via = tables.TemplateColumn(
'{% for role in record.via %}'
'<a href="{% url "a2-manager-role-members" pk=role.pk %}">{{ role }}</a>{% if not forloop.last %}, {% endif %}'
'{% endfor %}',
verbose_name=_('Inherited from'), orderable=False)
class Meta(UserTable.Meta):
pass

View File

@ -13,10 +13,13 @@
#
# 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.utils.encoding import force_bytes
from django.utils.encoding import force_text
from .utils import login
from django.utils.encoding import force_bytes, force_text
from authentic2.custom_user.models import User
from authentic2.a2_rbac.models import Role
from .utils import login, text_content
def test_manager_role_export(app, admin, ou1, role_ou1, ou2, role_ou2):
@ -88,3 +91,23 @@ def test_manager_role_name_uniqueness_multiple_ou(app, admin, ou1):
response.form.set('name', 'Role1')
response = response.form.submit('Save')
assert response.pyquery('.error').text() == 'Name already used'
def test_role_members_via(app, admin):
user1 = User.objects.create(username='user1')
user2 = User.objects.create(username='user2')
role1 = Role.objects.create(name='role1')
role2 = Role.objects.create(name='role2')
role1.add_child(role2)
user1.roles.add(role1)
user2.roles.add(role2)
response = login(app, admin, '/manage/roles/%s/' % role1.id)
rows = list(zip([text_content(el) for el in response.pyquery('tr td.username')],
[text_content(el) for el in response.pyquery('tr td.direct')],
[text_content(el) for el in response.pyquery('tr td.via')]))
assert rows == [
('user1', '', ''),
('user2', '', 'role2'),
]

View File

@ -234,3 +234,9 @@ def run_on_commit_hooks():
def call_command(*args, **kwargs):
with run_on_commit_hooks():
return django_call_command(*args, **kwargs)
def text_content(node):
'''Extract text content from node and all its children. Equivalent to
xmlNodeGetContent from libxml.'''
return u''.join(node.itertext())