From 01d35ea9c06b050fd10895f4c580a5097fd1472f Mon Sep 17 00:00:00 2001 From: Marliana Lara Date: Tue, 13 Mar 2018 16:53:00 -0400 Subject: [PATCH] Show organizations based on more granular RBAC roles --- .../edit-credentials.controller.js | 3 +- .../credentials/legacy.credentials.js | 2 +- .../edit/inventory-edit.controller.js | 8 ++--- .../src/notifications/notifications.list.js | 1 + .../edit/organizations-edit.controller.js | 9 +++-- .../projects/edit/projects-edit.controller.js | 2 +- awx/ui/client/src/shared/directives.js | 12 +++++-- .../org-admin-lookup.factory.js | 36 +++++++++++++++++-- .../src/shared/stateDefinitions.factory.js | 8 ++++- .../edit-workflow/workflow-edit.controller.js | 2 +- 10 files changed, 67 insertions(+), 16 deletions(-) diff --git a/awx/ui/client/features/credentials/edit-credentials.controller.js b/awx/ui/client/features/credentials/edit-credentials.controller.js index cbe1d9cb3b..d94c6163c2 100644 --- a/awx/ui/client/features/credentials/edit-credentials.controller.js +++ b/awx/ui/client/features/credentials/edit-credentials.controller.js @@ -43,10 +43,11 @@ function EditCredentialsController (models, $state, $scope, strings, componentsS } const isOrgAdmin = _.some(me.get('related.admin_of_organizations.results'), (org) => org.id === organization.get('id')); + const isOrgCredentialAdmin = organization.search({ role_level: 'credential_admin_role' }).then((data) => data); const isSuperuser = me.get('is_superuser'); const isCurrentAuthor = Boolean(credential.get('summary_fields.created_by.id') === me.get('id')); vm.form.organization._disabled = true; - if (isSuperuser || isOrgAdmin || (credential.get('organization') === null && isCurrentAuthor)) { + if (isSuperuser || isOrgAdmin || isOrgCredentialAdmin || (credential.get('organization') === null && isCurrentAuthor)) { vm.form.organization._disabled = false; } diff --git a/awx/ui/client/features/credentials/legacy.credentials.js b/awx/ui/client/features/credentials/legacy.credentials.js index c294207dea..07cee1329d 100644 --- a/awx/ui/client/features/credentials/legacy.credentials.js +++ b/awx/ui/client/features/credentials/legacy.credentials.js @@ -238,7 +238,7 @@ function LegacyCredentialsService () { value: { page_size: 5, order_by: 'name', - role_level: 'admin_role' + role_level: 'credential_admin_role' }, dynamic: true, squash: '' diff --git a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js index 37911d6afe..8f96ae9f6f 100644 --- a/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js +++ b/awx/ui/client/src/inventories-hosts/inventories/standard-inventory/edit/inventory-edit.controller.js @@ -47,10 +47,10 @@ function InventoriesEdit($scope, $location, field_id: 'inventory_inventory_variables' }); - OrgAdminLookup.checkForAdminAccess({organization: inventoryData.organization}) - .then(function(canEditOrg){ - $scope.canEditOrg = canEditOrg; - }); + OrgAdminLookup.checkForRoleLevelAdminAccess(inventoryData.organization, 'inventory_admin_role') + .then(function(canEditOrg){ + $scope.canEditOrg = canEditOrg; + }); $scope.inventory_obj = inventoryData; $scope.inventory_name = inventoryData.name; diff --git a/awx/ui/client/src/notifications/notifications.list.js b/awx/ui/client/src/notifications/notifications.list.js index 74a809444d..d0d1afab40 100644 --- a/awx/ui/client/src/notifications/notifications.list.js +++ b/awx/ui/client/src/notifications/notifications.list.js @@ -20,6 +20,7 @@ export default ['i18n', 'templateUrl', function(i18n, templateUrl){ hover: false, emptyListText: i18n.sprintf(i18n._("This list is populated by notification templates added from the %sNotifications%s section"), " ", " "), basePath: 'notification_templates', + ngIf: 'current_user.is_superuser || isOrgAdmin', fields: { name: { key: true, diff --git a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js index d44ee45746..e0f637efdf 100644 --- a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js +++ b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js @@ -4,10 +4,10 @@ * All Rights Reserved *************************************************/ -export default ['$scope', '$location', '$stateParams', +export default ['$scope', '$location', '$stateParams', 'OrgAdminLookup', 'OrganizationForm', 'Rest', 'ProcessErrors', 'Prompt', 'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData', 'ConfigData', - function($scope, $location, $stateParams, + function($scope, $location, $stateParams, OrgAdminLookup, OrganizationForm, Rest, ProcessErrors, Prompt, GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData, ConfigData) { @@ -21,6 +21,11 @@ export default ['$scope', '$location', '$stateParams', init(); function init() { + OrgAdminLookup.checkForAdminAccess({organization: id}) + .then(function(isOrgAdmin){ + $scope.isOrgAdmin = isOrgAdmin; + }); + $scope.$watch('organization_obj.summary_fields.user_capabilities.edit', function(val) { if (val === false) { $scope.canAdd = false; diff --git a/awx/ui/client/src/projects/edit/projects-edit.controller.js b/awx/ui/client/src/projects/edit/projects-edit.controller.js index 538615a2fd..2aa9434c15 100644 --- a/awx/ui/client/src/projects/edit/projects-edit.controller.js +++ b/awx/ui/client/src/projects/edit/projects-edit.controller.js @@ -143,7 +143,7 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest', $scope.scm_type_class = "btn-disabled"; } - OrgAdminLookup.checkForAdminAccess({organization: data.organization}) + OrgAdminLookup.checkForRoleLevelAdminAccess(data.organization, 'project_admin_role') .then(function(canEditOrg){ $scope.canEditOrg = canEditOrg; }); diff --git a/awx/ui/client/src/shared/directives.js b/awx/ui/client/src/shared/directives.js index 5df24c2450..2205ca9193 100644 --- a/awx/ui/client/src/shared/directives.js +++ b/awx/ui/client/src/shared/directives.js @@ -501,7 +501,7 @@ function(ConfigurationUtils, i18n, $rootScope) { }]) // lookup Validate lookup value against API -.directive('awlookup', ['Rest', 'GetBasePath', '$q', function(Rest, GetBasePath, $q) { +.directive('awlookup', ['Rest', 'GetBasePath', '$q', '$state', function(Rest, GetBasePath, $q, $state) { return { require: 'ngModel', link: function(scope, elm, attrs, fieldCtrl) { @@ -668,7 +668,15 @@ function(ConfigurationUtils, i18n, $rootScope) { query += '&cloud=true&role_level=use_role'; break; case 'organization': - query += '&role_level=admin_role'; + if ($state.current.name.includes('inventories')) { + query += '&role_level=inventory_admin_role'; + } else if ($state.current.name.includes('templates.editWorkflowJobTemplate')) { + query += '&role_level=workflow_admin_role'; + } else if ($state.current.name.includes('projects')) { + query += '&role_level=project_admin_role'; + } else { + query += '&role_level=admin_role'; + } break; case 'inventory_script': query += '&role_level=admin_role&organization=' + scope.$resolve.inventoryData.summary_fields.organization.id; diff --git a/awx/ui/client/src/shared/org-admin-lookup/org-admin-lookup.factory.js b/awx/ui/client/src/shared/org-admin-lookup/org-admin-lookup.factory.js index 12bea302cc..3e86cd866c 100644 --- a/awx/ui/client/src/shared/org-admin-lookup/org-admin-lookup.factory.js +++ b/awx/ui/client/src/shared/org-admin-lookup/org-admin-lookup.factory.js @@ -5,8 +5,8 @@ *************************************************/ export default - ['Rest', 'Authorization', 'GetBasePath', '$rootScope', '$q', - function(Rest, Authorization, GetBasePath, $rootScope, $q){ + ['Rest', 'Authorization', 'GetBasePath', 'ProcessErrors', '$rootScope', '$q', + function(Rest, Authorization, GetBasePath, ProcessErrors, $rootScope, $q){ return { checkForAdminAccess: function(params) { // params.organization - id of the organization in question @@ -28,8 +28,38 @@ export default } return deferred.promise; - } + }, + checkForRoleLevelAdminAccess: function(organization_id, role_level) { + let deferred = $q.defer(); + let params = { + role_level, + id: organization_id + }; + + if(Authorization.getUserInfo('is_superuser') !== true) { + Rest.setUrl(GetBasePath('organizations')); + Rest.get({ params: params }) + .then(({data}) => { + if(data.count && data.count > 0) { + deferred.resolve(true); + } + else { + deferred.resolve(false); + } + }) + .catch(({data, status}) => { + ProcessErrors(null, data, status, null, { + hdr: 'Error!', + msg: 'Failed to get organization data based on role_level. Return status: ' + status + }); + }); + } + else { + deferred.resolve(true); + } + return deferred.promise; + } }; } ]; diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index bb3977a4f7..63182fa98f 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -848,7 +848,13 @@ function($injector, $stateExtender, $log, i18n) { // Need to change the role_level here b/c organizations and inventory scripts // don't have a "use_role", only "admin_role" and "read_role" if(list.iterator === "organization"){ - $stateParams[`${list.iterator}_search`].role_level = "admin_role"; + if ($state.current.name.includes('inventories')) { + $stateParams[`${list.iterator}_search`].role_level = "inventory_admin_role"; + } else if ($state.current.name.includes('projects')) { + $stateParams[`${list.iterator}_search`].role_level = "project_admin_role"; + } else if ($state.current.name.includes('templates.addWorkflowJobTemplate') || $state.current.name.includes('templates.editWorkflowJobTemplate')) { + $stateParams[`${list.iterator}_search`].role_level = "workflow_admin_role"; + } } if(list.iterator === "inventory_script"){ $stateParams[`${list.iterator}_search`].role_level = "admin_role"; diff --git a/awx/ui/client/src/templates/workflows/edit-workflow/workflow-edit.controller.js b/awx/ui/client/src/templates/workflows/edit-workflow/workflow-edit.controller.js index eead433902..7b1a2d7892 100644 --- a/awx/ui/client/src/templates/workflows/edit-workflow/workflow-edit.controller.js +++ b/awx/ui/client/src/templates/workflows/edit-workflow/workflow-edit.controller.js @@ -99,7 +99,7 @@ export default [ } if(workflowJobTemplateData.organization) { - OrgAdminLookup.checkForAdminAccess({organization: workflowJobTemplateData.organization}) + OrgAdminLookup.checkForRoleLevelAdminAccess(workflowJobTemplateData.organization, 'workflow_admin_role') .then(function(canEditOrg){ $scope.canEditOrg = canEditOrg; });