Projet

Général

Profil

0001-manager-show-indirect-members-of-roles-real-roles-44.patch

Benjamin Dauvergne, 12 juillet 2020 09:29

Télécharger (4,84 ko)

Voir les différences:

Subject: [PATCH] manager: show indirect members of roles real roles (#44927)

 src/authentic2/manager/role_views.py |  6 ++++--
 src/authentic2/manager/tables.py     |  5 +++++
 tests/test_role_manager.py           | 29 +++++++++++++++++++++++++---
 tests/utils.py                       | 19 ++++++++++++++++++
 4 files changed, 54 insertions(+), 5 deletions(-)
src/authentic2/manager/role_views.py
23 23
from django.views.generic.detail import SingleObjectMixin
24 24
from django.contrib import messages
25 25
from django.contrib.contenttypes.models import ContentType
26
from django.db.models.query import Q
26
from django.db.models.query import Q, Prefetch
27 27
from django.db.models import Count
28 28
from django.contrib.auth import get_user_model
29 29

  
......
158 158
        self._can_manage_members = value
159 159

  
160 160
    def get_table_queryset(self):
161
        return self.object.all_members()
161
        children = self.object.children(include_self=False)
162
        via_prefetch = Prefetch('roles', queryset=children, to_attr='via')
163
        return self.object.all_members().prefetch_related(via_prefetch)
162 164

  
163 165
    def form_valid(self, form):
164 166
        user = form.cleaned_data['user']
src/authentic2/manager/tables.py
68 68
class RoleMembersTable(UserTable):
69 69
    direct = tables.BooleanColumn(verbose_name=_('Direct member'),
70 70
                                  orderable=False)
71
    via = tables.TemplateColumn(
72
        '{% for role in record.via %}'
73
        '<a href="{% url "a2-manager-role-members" pk=role.pk %}">{{ role }}</a>{% if not forloop.last %}, {% endif %}'
74
        '{% endfor %}',
75
        verbose_name=_('Inherited from'), orderable=False)
71 76

  
72 77
    class Meta(UserTable.Meta):
73 78
        pass
tests/test_role_manager.py
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
from django.utils.encoding import force_bytes
17
from django.utils.encoding import force_text
18 16

  
19
from .utils import login
17
from django.utils.encoding import force_bytes, force_text
18

  
19
from authentic2.custom_user.models import User
20
from authentic2.a2_rbac.models import Role
21

  
22
from .utils import login, text_content
20 23

  
21 24

  
22 25
def test_manager_role_export(app, admin, ou1, role_ou1, ou2, role_ou2):
......
88 91
    response.form.set('name', 'Role1')
89 92
    response = response.form.submit('Save')
90 93
    assert response.pyquery('.error').text() == 'Name already used'
94

  
95

  
96
def test_role_members_via(app, admin):
97
    user1 = User.objects.create(username='user1')
98
    user2 = User.objects.create(username='user2')
99
    role1 = Role.objects.create(name='role1')
100
    role2 = Role.objects.create(name='role2')
101

  
102
    role1.add_child(role2)
103
    user1.roles.add(role1)
104
    user2.roles.add(role2)
105

  
106
    response = login(app, admin, '/manage/roles/%s/' % role1.id)
107
    rows = list(zip([text_content(el) for el in response.pyquery('tr td.username')],
108
               [text_content(el) for el in response.pyquery('tr td.direct')],
109
               [text_content(el) for el in response.pyquery('tr td.via')]))
110
    assert rows == [
111
        ('user1', '✔', ''),
112
        ('user2', '✘', 'role2'),
113
    ]
tests/utils.py
215 215
    select2_field_id = response.pyquery('select')[0].attrib['data-field_id']
216 216
    select2_response = app.get(select2_url, params={'field_id': select2_field_id, 'term': term})
217 217
    return select2_response.json
218

  
219

  
220
def text_content(node):
221
    '''Extract text content from node and all its children. Equivalent to
222
       xmlNodeGetContent from libxml.'''
223

  
224
    if node is None:
225
        return ''
226

  
227
    def helper(node):
228
        s = []
229
        if node.text:
230
            s.append(node.text)
231
        for child in node:
232
            s.extend(helper(child))
233
            if child.tail:
234
                s.append(child.tail)
235
        return s
236
    return u''.join(helper(node))
218
-