mirror of
https://github.com/ansible/awx.git
synced 2026-03-26 21:35:01 -02:30
Fix rbac around credential access add button (#14290)
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { RolesAPI, TeamsAPI, UsersAPI, OrganizationsAPI } from 'api';
|
import { RolesAPI, TeamsAPI, UsersAPI } from 'api';
|
||||||
import { getQSConfig, parseQueryString } from 'util/qs';
|
import { getQSConfig, parseQueryString } from 'util/qs';
|
||||||
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
import useRequest, { useDeleteItems } from 'hooks/useRequest';
|
||||||
import { useUserProfile, useConfig } from 'contexts/Config';
|
import { useUserProfile } from 'contexts/Config';
|
||||||
import AddResourceRole from '../AddRole/AddResourceRole';
|
import AddResourceRole from '../AddRole/AddResourceRole';
|
||||||
import AlertModal from '../AlertModal';
|
import AlertModal from '../AlertModal';
|
||||||
import DataListToolbar from '../DataListToolbar';
|
import DataListToolbar from '../DataListToolbar';
|
||||||
@@ -25,8 +25,7 @@ const QS_CONFIG = getQSConfig('access', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function ResourceAccessList({ apiModel, resource }) {
|
function ResourceAccessList({ apiModel, resource }) {
|
||||||
const { isSuperUser, isOrgAdmin } = useUserProfile();
|
const { isSuperUser } = useUserProfile();
|
||||||
const { me } = useConfig();
|
|
||||||
const [submitError, setSubmitError] = useState(null);
|
const [submitError, setSubmitError] = useState(null);
|
||||||
const [deletionRecord, setDeletionRecord] = useState(null);
|
const [deletionRecord, setDeletionRecord] = useState(null);
|
||||||
const [deletionRole, setDeletionRole] = useState(null);
|
const [deletionRole, setDeletionRole] = useState(null);
|
||||||
@@ -34,42 +33,15 @@ function ResourceAccessList({ apiModel, resource }) {
|
|||||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const {
|
|
||||||
isLoading: isFetchingOrgAdmins,
|
|
||||||
error: errorFetchingOrgAdmins,
|
|
||||||
request: fetchOrgAdmins,
|
|
||||||
result: { isCredentialOrgAdmin },
|
|
||||||
} = useRequest(
|
|
||||||
useCallback(async () => {
|
|
||||||
if (
|
|
||||||
isSuperUser ||
|
|
||||||
resource.type !== 'credential' ||
|
|
||||||
!isOrgAdmin ||
|
|
||||||
!resource?.organization
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
data: { count },
|
|
||||||
} = await OrganizationsAPI.readAdmins(resource.organization, {
|
|
||||||
id: me.id,
|
|
||||||
});
|
|
||||||
return { isCredentialOrgAdmin: !!count };
|
|
||||||
}, [me.id, isOrgAdmin, isSuperUser, resource.type, resource.organization]),
|
|
||||||
{
|
|
||||||
isCredentialOrgAdmin: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchOrgAdmins();
|
|
||||||
}, [fetchOrgAdmins]);
|
|
||||||
|
|
||||||
let canAddAdditionalControls = false;
|
let canAddAdditionalControls = false;
|
||||||
if (isSuperUser) {
|
if (isSuperUser) {
|
||||||
canAddAdditionalControls = true;
|
canAddAdditionalControls = true;
|
||||||
}
|
}
|
||||||
if (resource.type === 'credential' && isOrgAdmin && isCredentialOrgAdmin) {
|
if (
|
||||||
|
resource.type === 'credential' &&
|
||||||
|
resource?.summary_fields?.user_capabilities?.edit &&
|
||||||
|
resource?.organization
|
||||||
|
) {
|
||||||
canAddAdditionalControls = true;
|
canAddAdditionalControls = true;
|
||||||
}
|
}
|
||||||
if (resource.type !== 'credential') {
|
if (resource.type !== 'credential') {
|
||||||
@@ -195,8 +167,8 @@ function ResourceAccessList({ apiModel, resource }) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PaginatedTable
|
<PaginatedTable
|
||||||
error={contentError || errorFetchingOrgAdmins}
|
error={contentError}
|
||||||
hasContentLoading={isLoading || isDeleteLoading || isFetchingOrgAdmins}
|
hasContentLoading={isLoading || isDeleteLoading}
|
||||||
items={accessRecords}
|
items={accessRecords}
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
pluralizedItemName={t`Roles`}
|
pluralizedItemName={t`Roles`}
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ describe('<ResourceAccessList />', () => {
|
|||||||
expect(wrapper.find('ToolbarAddButton').length).toEqual(1);
|
expect(wrapper.find('ToolbarAddButton').length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not show add button for non system admin & non org admin', async () => {
|
test('should not show add button for a user without edit permissions on the credential', async () => {
|
||||||
useUserProfile.mockImplementation(() => {
|
useUserProfile.mockImplementation(() => {
|
||||||
return {
|
return {
|
||||||
isSuperUser: false,
|
isSuperUser: false,
|
||||||
@@ -476,7 +476,21 @@ describe('<ResourceAccessList />', () => {
|
|||||||
let wrapper;
|
let wrapper;
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<ResourceAccessList resource={credential} apiModel={CredentialsAPI} />,
|
<ResourceAccessList
|
||||||
|
resource={{
|
||||||
|
...credential,
|
||||||
|
summary_fields: {
|
||||||
|
...credential.summary_fields,
|
||||||
|
user_capabilities: {
|
||||||
|
edit: false,
|
||||||
|
delete: false,
|
||||||
|
copy: false,
|
||||||
|
use: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
apiModel={CredentialsAPI}
|
||||||
|
/>,
|
||||||
{ context: { router: { credentialHistory } } }
|
{ context: { router: { credentialHistory } } }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user