From d72a2a15ec8a043c4d3084b5149f33040f268b6d Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 12 Dec 2024 20:07:49 -0600 Subject: [PATCH] fix: fix behavior when editing Roles for a User per proper UUID fields i guess --- src/wuttaweb/forms/schema.py | 10 +++++++++- src/wuttaweb/views/users.py | 3 +-- tests/forms/test_schema.py | 10 +++++++++- tests/forms/test_widgets.py | 11 +++++++---- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/wuttaweb/forms/schema.py b/src/wuttaweb/forms/schema.py index c414376..6fa39c9 100644 --- a/src/wuttaweb/forms/schema.py +++ b/src/wuttaweb/forms/schema.py @@ -453,16 +453,24 @@ class RoleRefs(WuttaSet): if 'values' not in kwargs: model = self.app.model auth = self.app.get_auth_handler() + + # avoid built-ins which cannot be assigned to users avoid = { auth.get_role_authenticated(self.session), auth.get_role_anonymous(self.session), } avoid = set([role.uuid for role in avoid]) + + # also avoid admin unless current user is root + if not self.request.is_root: + avoid.add(auth.get_role_administrator(self.session).uuid) + + # everything else can be (un)assigned for users roles = self.session.query(model.Role)\ .filter(~model.Role.uuid.in_(avoid))\ .order_by(model.Role.name)\ .all() - values = [(role.uuid, role.name) for role in roles] + values = [(role.uuid.hex, role.name) for role in roles] kwargs['values'] = values return widgets.RoleRefsWidget(self.request, **kwargs) diff --git a/src/wuttaweb/views/users.py b/src/wuttaweb/views/users.py index f679061..5eac845 100644 --- a/src/wuttaweb/views/users.py +++ b/src/wuttaweb/views/users.py @@ -134,9 +134,8 @@ class UserView(MasterView): # roles f.append('roles') f.set_node('roles', RoleRefs(self.request)) - if not self.creating: - f.set_default('roles', [role.uuid for role in user.roles]) + f.set_default('roles', [role.uuid.hex for role in user.roles]) def unique_username(self, node, value): """ """ diff --git a/tests/forms/test_schema.py b/tests/forms/test_schema.py index 299add2..a9eabf8 100644 --- a/tests/forms/test_schema.py +++ b/tests/forms/test_schema.py @@ -332,13 +332,21 @@ class TestRoleRefs(DataTestCase): self.session.add(blokes) self.session.commit() - # default values for widget includes all but: authed, anon + # with root access, default values include: admin, blokes + self.request.is_root = True typ = mod.RoleRefs(self.request, session=self.session) widget = typ.widget_maker() self.assertEqual(len(widget.values), 2) self.assertEqual(widget.values[0][1], "Administrator") self.assertEqual(widget.values[1][1], "Blokes") + # without root, default values include: blokes + self.request.is_root = False + typ = mod.RoleRefs(self.request, session=self.session) + widget = typ.widget_maker() + self.assertEqual(len(widget.values), 1) + self.assertEqual(widget.values[0][1], "Blokes") + class TestPermissions(DataTestCase): diff --git a/tests/forms/test_widgets.py b/tests/forms/test_widgets.py index 4e3a2e6..a49bdf5 100644 --- a/tests/forms/test_widgets.py +++ b/tests/forms/test_widgets.py @@ -210,14 +210,17 @@ class TestRoleRefsWidget(WebTestCase): # editable values list *excludes* admin (by default) html = widget.serialize(field, {admin.uuid, blokes.uuid}) - self.assertNotIn(str(admin.uuid), html) - self.assertIn(str(blokes.uuid), html) + self.assertNotIn(str(admin.uuid.hex), html) + self.assertIn(str(blokes.uuid.hex), html) # but admin is included for root user self.request.is_root = True + node = colander.SchemaNode(RoleRefs(self.request, session=self.session)) + field = self.make_field(node) + widget = field.widget html = widget.serialize(field, {admin.uuid, blokes.uuid}) - self.assertIn(str(admin.uuid), html) - self.assertIn(str(blokes.uuid), html) + self.assertIn(str(admin.uuid.hex), html) + self.assertIn(str(blokes.uuid.hex), html) class TestUserRefsWidget(WebTestCase):