diff --git a/tailbone/views/roles.py b/tailbone/views/roles.py index 78389d5d..61de606a 100644 --- a/tailbone/views/roles.py +++ b/tailbone/views/roles.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -54,6 +54,7 @@ class RoleView(PrincipalMasterView): touchable = True labels = { + 'adminish': "Admin-ish", 'sync_me': "Sync Attrs & Perms", } @@ -68,6 +69,7 @@ class RoleView(PrincipalMasterView): form_fields = [ 'name', + 'adminish', 'session_timeout', 'notes', 'sync_me', @@ -112,6 +114,10 @@ class RoleView(PrincipalMasterView): if role is administrator_role(self.Session()): return self.request.is_root + # only "admin" can edit "admin-ish" roles + if role.adminish: + return self.request.is_admin + # can edit Authenticated only if user has permission if role is authenticated_role(self.Session()): return self.has_perm('edit_authenticated') @@ -143,6 +149,10 @@ class RoleView(PrincipalMasterView): if role is guest_role(self.Session()): return False + # only "admin" can delete "admin-ish" roles + if role.adminish: + return self.request.is_admin + # current user can delete their own roles, only if they have permission user = self.request.user if user and role in user.roles: @@ -169,6 +179,10 @@ class RoleView(PrincipalMasterView): # name f.set_validator('name', self.unique_name) + # adminish + if not self.request.is_admin: + f.remove('adminish') + # session_timeout f.set_renderer('session_timeout', self.render_session_timeout) if self.editing and role is guest_role(self.Session()): diff --git a/tailbone/views/users.py b/tailbone/views/users.py index 1fb1250d..0c5821b5 100644 --- a/tailbone/views/users.py +++ b/tailbone/views/users.py @@ -27,6 +27,7 @@ User Views from __future__ import unicode_literals, absolute_import import six +import sqlalchemy as sa from sqlalchemy import orm from rattail.db.model import User, UserEvent @@ -276,13 +277,21 @@ class UserView(PrincipalMasterView): authenticated_role(self.Session()).uuid, ] - # only allow "root" user to change admin role membership + # only allow "root" user to change true admin role membership if not self.request.is_root: excluded.append(administrator_role(self.Session()).uuid) - return self.Session.query(model.Role)\ - .filter(~model.Role.uuid.in_(excluded))\ - .order_by(model.Role.name) + # basic list, minus exclusions so far + roles = self.Session.query(model.Role)\ + .filter(~model.Role.uuid.in_(excluded)) + + # only allow "admin" user to change admin-ish role memberships + if not self.request.is_admin: + roles = roles.filter(sa.or_( + model.Role.adminish == False, + model.Role.adminish == None)) + + return roles.order_by(model.Role.name) def objectify(self, form, data=None): model = self.model