Merge pull request #2919 from anoek/2918

Several system auditor fixes to allow SA's to read and see things
This commit is contained in:
Akita Noek
2016-07-11 15:23:36 -04:00
committed by GitHub
5 changed files with 26 additions and 27 deletions

View File

@@ -1401,7 +1401,7 @@ class OrganizationCredentialList(SubListCreateAPIView):
user_visible = Credential.accessible_objects(self.request.user, 'read_role').all() user_visible = Credential.accessible_objects(self.request.user, 'read_role').all()
org_set = Credential.accessible_objects(organization.admin_role, 'read_role').all() org_set = Credential.accessible_objects(organization.admin_role, 'read_role').all()
if self.request.user.is_superuser: if self.request.user.is_superuser or self.request.user.is_system_auditor:
return org_set return org_set
return org_set & user_visible return org_set & user_visible
@@ -2591,7 +2591,7 @@ class SystemJobTemplateList(ListAPIView):
serializer_class = SystemJobTemplateSerializer serializer_class = SystemJobTemplateSerializer
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.is_superuser: if not request.user.is_superuser and not request.user.is_system_auditor:
raise PermissionDenied("Superuser privileges needed.") raise PermissionDenied("Superuser privileges needed.")
return super(SystemJobTemplateList, self).get(request, *args, **kwargs) return super(SystemJobTemplateList, self).get(request, *args, **kwargs)
@@ -3321,7 +3321,7 @@ class SystemJobList(ListCreateAPIView):
serializer_class = SystemJobListSerializer serializer_class = SystemJobListSerializer
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not request.user.is_superuser: if not request.user.is_superuser and not request.user.is_system_auditor:
raise PermissionDenied("Superuser privileges needed.") raise PermissionDenied("Superuser privileges needed.")
return super(SystemJobList, self).get(request, *args, **kwargs) return super(SystemJobList, self).get(request, *args, **kwargs)
@@ -3625,8 +3625,6 @@ class RoleList(ListAPIView):
new_in_300 = True new_in_300 = True
def get_queryset(self): def get_queryset(self):
if self.request.user.is_superuser:
return Role.objects.all()
return Role.visible_roles(self.request.user) return Role.visible_roles(self.request.user)

View File

@@ -139,7 +139,7 @@ class BaseAccess(object):
self.user = user self.user = user
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.all() return self.model.objects.all()
else: else:
return self.model.objects.none() return self.model.objects.none()
@@ -221,7 +221,7 @@ class UserAccess(BaseAccess):
model = User model = User
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return User.objects.all() return User.objects.all()
if tower_settings.ORG_ADMINS_CAN_SEE_ALL_USERS and \ if tower_settings.ORG_ADMINS_CAN_SEE_ALL_USERS and \
@@ -718,7 +718,7 @@ class ProjectAccess(BaseAccess):
model = Project model = Project
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.all() return self.model.objects.all()
qs = self.model.accessible_objects(self.user, 'read_role') qs = self.model.accessible_objects(self.user, 'read_role')
return qs.select_related('modified_by', 'credential', 'current_job', 'last_job').all() return qs.select_related('modified_by', 'credential', 'current_job', 'last_job').all()
@@ -752,7 +752,7 @@ class ProjectUpdateAccess(BaseAccess):
model = ProjectUpdate model = ProjectUpdate
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.all() return self.model.objects.all()
qs = ProjectUpdate.objects.distinct() qs = ProjectUpdate.objects.distinct()
qs = qs.select_related('created_by', 'modified_by', 'project') qs = qs.select_related('created_by', 'modified_by', 'project')
@@ -788,7 +788,7 @@ class JobTemplateAccess(BaseAccess):
model = JobTemplate model = JobTemplate
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
qs = self.model.objects.all() qs = self.model.objects.all()
else: else:
qs = self.model.accessible_objects(self.user, 'read_role') qs = self.model.accessible_objects(self.user, 'read_role')
@@ -979,7 +979,7 @@ class JobAccess(BaseAccess):
qs = qs.select_related('created_by', 'modified_by', 'job_template', 'inventory', qs = qs.select_related('created_by', 'modified_by', 'job_template', 'inventory',
'project', 'credential', 'cloud_credential', 'job_template') 'project', 'credential', 'cloud_credential', 'job_template')
qs = qs.prefetch_related('unified_job_template') qs = qs.prefetch_related('unified_job_template')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
qs_jt = qs.filter( qs_jt = qs.filter(
@@ -1086,7 +1086,7 @@ class AdHocCommandAccess(BaseAccess):
qs = self.model.objects.distinct() qs = self.model.objects.distinct()
qs = qs.select_related('created_by', 'modified_by', 'inventory', qs = qs.select_related('created_by', 'modified_by', 'inventory',
'credential') 'credential')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
inventory_qs = Inventory.accessible_objects(self.user, 'read_role') inventory_qs = Inventory.accessible_objects(self.user, 'read_role')
@@ -1147,7 +1147,7 @@ class AdHocCommandEventAccess(BaseAccess):
qs = self.model.objects.distinct() qs = self.model.objects.distinct()
qs = qs.select_related('ad_hoc_command', 'host') qs = qs.select_related('ad_hoc_command', 'host')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
ad_hoc_command_qs = self.user.get_queryset(AdHocCommand) ad_hoc_command_qs = self.user.get_queryset(AdHocCommand)
host_qs = self.user.get_queryset(Host) host_qs = self.user.get_queryset(Host)
@@ -1173,7 +1173,7 @@ class JobHostSummaryAccess(BaseAccess):
def get_queryset(self): def get_queryset(self):
qs = self.model.objects qs = self.model.objects
qs = qs.select_related('job', 'job__job_template', 'host') qs = qs.select_related('job', 'job__job_template', 'host')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
job_qs = self.user.get_queryset(Job) job_qs = self.user.get_queryset(Job)
host_qs = self.user.get_queryset(Host) host_qs = self.user.get_queryset(Host)
@@ -1205,7 +1205,7 @@ class JobEventAccess(BaseAccess):
event_data__icontains='"ansible_job_id": "', event_data__icontains='"ansible_job_id": "',
event_data__contains='"module_name": "async_status"') event_data__contains='"module_name": "async_status"')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
job_qs = self.user.get_queryset(Job) job_qs = self.user.get_queryset(Job)
@@ -1318,7 +1318,7 @@ class ScheduleAccess(BaseAccess):
qs = self.model.objects.all() qs = self.model.objects.all()
qs = qs.select_related('created_by', 'modified_by') qs = qs.select_related('created_by', 'modified_by')
qs = qs.prefetch_related('unified_job_template') qs = qs.prefetch_related('unified_job_template')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all() return qs.all()
job_template_qs = self.user.get_queryset(JobTemplate) job_template_qs = self.user.get_queryset(JobTemplate)
inventory_source_qs = self.user.get_queryset(InventorySource) inventory_source_qs = self.user.get_queryset(InventorySource)
@@ -1369,12 +1369,13 @@ class NotificationTemplateAccess(BaseAccess):
def get_queryset(self): def get_queryset(self):
qs = self.model.objects.all() qs = self.model.objects.all()
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs return qs
return self.model.objects.filter(organization__in=Organization.accessible_objects(self.user, 'admin_role').all()) return self.model.objects.filter(organization__in=Organization.accessible_objects(self.user, 'admin_role').all())
@check_superuser
def can_read(self, obj): def can_read(self, obj):
if self.user.is_superuser or self.user.is_system_auditor:
return True
if obj.organization is not None: if obj.organization is not None:
return self.user in obj.organization.admin_role return self.user in obj.organization.admin_role
return False return False
@@ -1413,7 +1414,7 @@ class NotificationAccess(BaseAccess):
def get_queryset(self): def get_queryset(self):
qs = self.model.objects.all() qs = self.model.objects.all()
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs return qs
return self.model.objects.filter(notification_template__organization__in=Organization.accessible_objects(self.user, 'admin_role')) return self.model.objects.filter(notification_template__organization__in=Organization.accessible_objects(self.user, 'admin_role'))
@@ -1430,7 +1431,7 @@ class LabelAccess(BaseAccess):
model = Label model = Label
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.all() return self.model.objects.all()
return self.model.objects.filter( return self.model.objects.filter(
organization__in=Organization.accessible_objects(self.user, 'read_role') organization__in=Organization.accessible_objects(self.user, 'read_role')
@@ -1493,9 +1494,7 @@ class ActivityStreamAccess(BaseAccess):
'inventory_update', 'credential', 'team', 'project', 'project_update', 'inventory_update', 'credential', 'team', 'project', 'project_update',
'permission', 'job_template', 'job', 'ad_hoc_command', 'permission', 'job_template', 'job', 'ad_hoc_command',
'notification_template', 'notification', 'label', 'role') 'notification_template', 'notification', 'label', 'role')
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return qs.all()
if self.user in Role.singleton('system_auditor'):
return qs.all() return qs.all()
inventory_set = Inventory.accessible_objects(self.user, 'read_role') inventory_set = Inventory.accessible_objects(self.user, 'read_role')
@@ -1543,7 +1542,7 @@ class CustomInventoryScriptAccess(BaseAccess):
model = CustomInventoryScript model = CustomInventoryScript
def get_queryset(self): def get_queryset(self):
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return self.model.objects.distinct().all() return self.model.objects.distinct().all()
return self.model.accessible_objects(self.user, 'read_role').all() return self.model.accessible_objects(self.user, 'read_role').all()
@@ -1599,7 +1598,7 @@ class RoleAccess(BaseAccess):
def can_read(self, obj): def can_read(self, obj):
if not obj: if not obj:
return False return False
if self.user.is_superuser: if self.user.is_superuser or self.user.is_system_auditor:
return True return True
if obj.object_id: if obj.object_id:

View File

@@ -881,6 +881,7 @@ var tower = angular.module('Tower', [
} }
// If browser refresh, set the user_is_superuser value // If browser refresh, set the user_is_superuser value
$rootScope.user_is_superuser = Authorization.getUserInfo('is_superuser'); $rootScope.user_is_superuser = Authorization.getUserInfo('is_superuser');
$rootScope.user_is_system_auditor = Authorization.getUserInfo('is_system_auditor');
// state the user refreshes we want to open the socket, except if the user is on the login page, which should happen after the user logs in (see the AuthService module for that call to OpenSocket) // state the user refreshes we want to open the socket, except if the user is on the login page, which should happen after the user logs in (see the AuthService module for that call to OpenSocket)
if(!_.contains($location.$$url, '/login')){ if(!_.contains($location.$$url, '/login')){
ConfigService.getConfig().then(function(){ ConfigService.getConfig().then(function(){

View File

@@ -137,6 +137,7 @@ export default ['$log', '$cookieStore', '$compile', '$window', '$rootScope',
$rootScope.sessionTimer = timer; $rootScope.sessionTimer = timer;
$rootScope.$emit('OpenSocket'); $rootScope.$emit('OpenSocket');
$rootScope.user_is_superuser = data.results[0].is_superuser; $rootScope.user_is_superuser = data.results[0].is_superuser;
$rootScope.user_is_system_auditor = data.results[0].is_system_auditor;
scope.$emit('AuthorizationGetLicense'); scope.$emit('AuthorizationGetLicense');
}); });
}) })

View File

@@ -24,7 +24,7 @@
Add passwords, SSH keys, etc. for Tower to use when launching jobs against machines, or when syncing inventories or projects. Add passwords, SSH keys, etc. for Tower to use when launching jobs against machines, or when syncing inventories or projects.
</p> </p>
</a> </a>
<a ui-sref="managementJobsList" class="SetupItem" ng-if="user_is_superuser"> <a ui-sref="managementJobsList" class="SetupItem" ng-if="user_is_superuser || user_is_system_auditor">
<h4 class="SetupItem-title">Management Jobs</h4> <h4 class="SetupItem-title">Management Jobs</h4>
<p class="SetupItem-description"> <p class="SetupItem-description">
Manage the cleanup of old job history, activity streams, data marked for deletion, and system tracking info. Manage the cleanup of old job history, activity streams, data marked for deletion, and system tracking info.
@@ -37,7 +37,7 @@
</p> </p>
</a> </a>
<a ui-sref="notifications" class="SetupItem" <a ui-sref="notifications" class="SetupItem"
ng-if="orgAdmin"> ng-if="orgAdmin || user_is_system_auditor || user_is_superuser">
<h4 class="SetupItem-title">Notifications</h4> <h4 class="SetupItem-title">Notifications</h4>
<p class="SetupItem-description"> <p class="SetupItem-description">
Create templates for sending notifications with Email, HipChat, Slack, and SMS. Create templates for sending notifications with Email, HipChat, Slack, and SMS.