Fix rbac around credential access add button (#14290)

This commit is contained in:
Michael Abashian
2023-08-03 09:18:21 -04:00
committed by GitHub
parent 7e4cf859f5
commit aec9a9ca56
2 changed files with 26 additions and 40 deletions

View File

@@ -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`}

View File

@@ -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 } } }
); );
}); });