From 47893613a2a6c6a1bd6f7bf2df4e2aa7af14d250 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Thu, 30 Jun 2016 10:55:54 -0400 Subject: [PATCH 1/2] ensure the singleton roles show up for sys auditor / sys admins --- awx/api/views.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/awx/api/views.py b/awx/api/views.py index dec8307e05..fb903da677 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1192,6 +1192,13 @@ class UserRolesList(SubListCreateAttachDetachAPIView): if not self.request.user.can_access(User, 'read', u): raise PermissionDenied() content_type = ContentType.objects.get_for_model(User) + + sys_admin = Role.singleton(ROLE_SINGLETON_SYSTEM_ADMINISTRATOR) + sys_audit = Role.singleton(ROLE_SINGLETON_SYSTEM_AUDITOR) + + if self.request.user in sys_admin or self.request.user in sys_audit: + return u.roles.all().exclude(content_type=content_type, object_id=u.id) + return Role.filter_visible_roles(self.request.user, u.roles.all()) \ .exclude(content_type=content_type, object_id=u.id) From 16bc0cdf0b7422c1d6694df7acf7f1a222ef0625 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 1 Jul 2016 10:38:02 -0400 Subject: [PATCH 2/2] add helper decorator to ensure signleton roles see the proper role list --- awx/api/views.py | 6 ------ awx/main/models/rbac.py | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index fb903da677..e12e9eac5d 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1193,12 +1193,6 @@ class UserRolesList(SubListCreateAttachDetachAPIView): raise PermissionDenied() content_type = ContentType.objects.get_for_model(User) - sys_admin = Role.singleton(ROLE_SINGLETON_SYSTEM_ADMINISTRATOR) - sys_audit = Role.singleton(ROLE_SINGLETON_SYSTEM_AUDITOR) - - if self.request.user in sys_admin or self.request.user in sys_audit: - return u.roles.all().exclude(content_type=content_type, object_id=u.id) - return Role.filter_visible_roles(self.request.user, u.roles.all()) \ .exclude(content_type=content_type, object_id=u.id) diff --git a/awx/main/models/rbac.py b/awx/main/models/rbac.py index 4edeb587c7..697d51f1e2 100644 --- a/awx/main/models/rbac.py +++ b/awx/main/models/rbac.py @@ -61,6 +61,24 @@ role_descriptions = { tls = threading.local() # thread local storage + +def check_singleton(func): + ''' + check_singleton is a decorator that checks if a user given + to a `visible_roles` method is in either of our singleton roles (Admin, Auditor) + and if so, returns their full list of roles without filtering. + ''' + def wrapper(*args, **kwargs): + sys_admin = Role.singleton(ROLE_SINGLETON_SYSTEM_ADMINISTRATOR) + sys_audit = Role.singleton(ROLE_SINGLETON_SYSTEM_AUDITOR) + user = args[0] + if user in sys_admin or user in sys_audit: + if len(args) == 2: + return args[1] + return user.roles.all() + return func(*args, **kwargs) + return wrapper + @contextlib.contextmanager def batch_role_ancestor_rebuilding(allow_nesting=False): ''' @@ -352,6 +370,7 @@ class Role(models.Model): @staticmethod + @check_singleton def visible_roles(user): sql_params = { 'ancestors_table': Role.ancestors.through._meta.db_table, @@ -372,6 +391,7 @@ class Role(models.Model): return qs @staticmethod + @check_singleton def filter_visible_roles(user, roles_qs): sql_params = { 'ancestors_table': Role.ancestors.through._meta.db_table,