diff --git a/awx/api/views.py b/awx/api/views.py index efbbecf10e..189d687222 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -3830,7 +3830,16 @@ class RoleList(ListAPIView): new_in_300 = True def get_queryset(self): - return Role.visible_roles(self.request.user) + result = Role.visible_roles(self.request.user) + # Sanity check: is the requesting user an orphaned non-admin/auditor? + # if yes, make system admin/auditor mandatorily visible. + if not self.request.user.organizations.exists() and\ + not self.request.user.is_superuser and\ + not self.request.user.is_system_auditor: + mandatories = ('system_administrator', 'system_auditor') + super_qs = Role.objects.filter(singleton_name__in=mandatories) + result = result | super_qs + return result class RoleDetail(RetrieveAPIView): diff --git a/awx/main/models/rbac.py b/awx/main/models/rbac.py index 8592a9c632..f469c1a7ac 100644 --- a/awx/main/models/rbac.py +++ b/awx/main/models/rbac.py @@ -376,13 +376,12 @@ class Role(models.Model): @staticmethod @check_singleton - def visible_roles(user, include_super=True): + def visible_roles(user): sql_params = { 'ancestors_table': Role.ancestors.through._meta.db_table, 'parents_table': Role.parents.through._meta.db_table, 'roles_table': Role._meta.db_table, 'ids': ','.join(str(x) for x in user.roles.values_list('id', flat=True)), - 'mandatories': ','.join(('\'system_administrator\'', '\'system_auditor\'')), } qs = Role.objects.extra( @@ -395,17 +394,6 @@ class Role(models.Model): ) ''' % sql_params] ) - if include_super: - super_qs = Role.objects.extra( - where = [''' - %(roles_table)s.id IN ( - SELECT DISTINCT visible_roles_t3.id - FROM %(roles_table)s as visible_roles_t3 - WHERE visible_roles_t3.singleton_name IN (%(mandatories)s) - ) - ''' % sql_params] - ) - qs = qs | super_qs return qs @staticmethod