fix(docker): hide write buttons for non authorized [EE-6775] (#11260)
parent
d8e374fb76
commit
19a6a5c608
|
@ -79,7 +79,7 @@ const ngModule = angular
|
|||
)
|
||||
.component(
|
||||
'dockerConfigsDatatable',
|
||||
r2a(withUIRouter(ConfigsDatatable), [
|
||||
r2a(withUIRouter(withCurrentUser(ConfigsDatatable)), [
|
||||
'dataset',
|
||||
'onRemoveClick',
|
||||
'onRefresh',
|
||||
|
@ -121,7 +121,11 @@ const ngModule = angular
|
|||
.component('dockerEventsDatatable', r2a(EventsDatatable, ['dataset']))
|
||||
.component(
|
||||
'dockerSecretsDatatable',
|
||||
r2a(withUIRouter(SecretsDatatable), ['dataset', 'onRefresh', 'onRemove'])
|
||||
r2a(withUIRouter(withCurrentUser(SecretsDatatable)), [
|
||||
'dataset',
|
||||
'onRefresh',
|
||||
'onRemove',
|
||||
])
|
||||
)
|
||||
.component(
|
||||
'dockerStacksDatatable',
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { Clipboard, Plus, Trash2 } from 'lucide-react';
|
||||
|
||||
import { Authorized, useAuthorizations } from '@/react/hooks/useUser';
|
||||
|
||||
import { Datatable, TableSettingsMenu } from '@@/datatables';
|
||||
import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh';
|
||||
import { useRepeater } from '@@/datatables/useRepeater';
|
||||
|
@ -26,6 +28,11 @@ export function ConfigsDatatable({ dataset, onRefresh, onRemoveClick }: Props) {
|
|||
|
||||
useRepeater(tableState.autoRefreshRate, onRefresh);
|
||||
|
||||
const hasWriteAccessQuery = useAuthorizations([
|
||||
'DockerConfigCreate',
|
||||
'DockerConfigDelete',
|
||||
]);
|
||||
|
||||
return (
|
||||
<Datatable
|
||||
dataset={dataset}
|
||||
|
@ -42,21 +49,33 @@ export function ConfigsDatatable({ dataset, onRefresh, onRemoveClick }: Props) {
|
|||
/>
|
||||
</TableSettingsMenu>
|
||||
)}
|
||||
renderTableActions={(selectedRows) => (
|
||||
<div className="flex items-center gap-3">
|
||||
<Button
|
||||
icon={Trash2}
|
||||
color="dangerlight"
|
||||
onClick={() => onRemoveClick(selectedRows)}
|
||||
disabled={selectedRows.length === 0}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
<Button icon={Plus} as={Link} props={{ to: 'docker.configs.new' }}>
|
||||
Add config
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
disableSelect={!hasWriteAccessQuery.authorized}
|
||||
renderTableActions={(selectedRows) =>
|
||||
hasWriteAccessQuery.authorized && (
|
||||
<div className="flex items-center gap-3">
|
||||
<Authorized authorizations="DockerConfigDelete">
|
||||
<Button
|
||||
icon={Trash2}
|
||||
color="dangerlight"
|
||||
onClick={() => onRemoveClick(selectedRows)}
|
||||
disabled={selectedRows.length === 0}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Authorized>
|
||||
|
||||
<Authorized authorizations="DockerConfigCreate">
|
||||
<Button
|
||||
icon={Plus}
|
||||
as={Link}
|
||||
props={{ to: 'docker.configs.new' }}
|
||||
>
|
||||
Add config
|
||||
</Button>
|
||||
</Authorized>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Lock, Plus, Trash2 } from 'lucide-react';
|
|||
|
||||
import { SecretViewModel } from '@/docker/models/secret';
|
||||
import { isoDate } from '@/portainer/filters/filters';
|
||||
import { Authorized, useAuthorizations } from '@/react/hooks/useUser';
|
||||
|
||||
import { buildNameColumn } from '@@/datatables/buildNameColumn';
|
||||
import { Datatable, TableSettingsMenu } from '@@/datatables';
|
||||
|
@ -53,6 +54,11 @@ export function SecretsDatatable({
|
|||
const tableState = useTableState(store, storageKey);
|
||||
useRepeater(tableState.autoRefreshRate, onRefresh);
|
||||
|
||||
const hasWriteAccessQuery = useAuthorizations([
|
||||
'DockerSecretCreate',
|
||||
'DockerSecretDelete',
|
||||
]);
|
||||
|
||||
return (
|
||||
<Datatable
|
||||
title="Secrets"
|
||||
|
@ -60,11 +66,14 @@ export function SecretsDatatable({
|
|||
columns={columns}
|
||||
dataset={dataset || []}
|
||||
isLoading={!dataset}
|
||||
disableSelect={!hasWriteAccessQuery.authorized}
|
||||
settingsManager={tableState}
|
||||
emptyContentLabel="No secret available."
|
||||
renderTableActions={(selectedItems) => (
|
||||
<TableActions selectedItems={selectedItems} onRemove={onRemove} />
|
||||
)}
|
||||
renderTableActions={(selectedItems) =>
|
||||
hasWriteAccessQuery.authorized && (
|
||||
<TableActions selectedItems={selectedItems} onRemove={onRemove} />
|
||||
)
|
||||
}
|
||||
renderTableSettings={() => (
|
||||
<TableSettingsMenu>
|
||||
<TableSettingsMenuAutoRefresh
|
||||
|
@ -86,26 +95,30 @@ function TableActions({
|
|||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
color="dangerlight"
|
||||
disabled={selectedItems.length === 0}
|
||||
onClick={() => onRemove(selectedItems)}
|
||||
icon={Trash2}
|
||||
className="!m-0"
|
||||
data-cy="secret-removeSecretButton"
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
<Authorized authorizations="DockerSecretDelete">
|
||||
<Button
|
||||
color="dangerlight"
|
||||
disabled={selectedItems.length === 0}
|
||||
onClick={() => onRemove(selectedItems)}
|
||||
icon={Trash2}
|
||||
className="!m-0"
|
||||
data-cy="secret-removeSecretButton"
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Authorized>
|
||||
|
||||
<Button
|
||||
as={Link}
|
||||
props={{ to: '.new' }}
|
||||
icon={Plus}
|
||||
className="!m-0"
|
||||
data-cy="secret-addSecretButton"
|
||||
>
|
||||
Add secret
|
||||
</Button>
|
||||
<Authorized authorizations="DockerSecretCreate">
|
||||
<Button
|
||||
as={Link}
|
||||
props={{ to: '.new' }}
|
||||
icon={Plus}
|
||||
className="!m-0"
|
||||
data-cy="secret-addSecretButton"
|
||||
>
|
||||
Add secret
|
||||
</Button>
|
||||
</Authorized>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -88,6 +88,14 @@ export function useIsEdgeAdmin({
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has some of the authorizations
|
||||
*
|
||||
* @param authorizations a list of authorizations to check
|
||||
* @param forceEnvironmentId to force the environment id, used where the environment id can't be loaded from the router, like sidebar
|
||||
* @param adminOnlyCE if true, will return false if the user is not an admin in CE
|
||||
* @returns query result with isLoading and authorized - authorized is true if the user has some of the authorizations
|
||||
*/
|
||||
export function useAuthorizations(
|
||||
authorizations: string | string[],
|
||||
forceEnvironmentId?: EnvironmentId,
|
||||
|
@ -137,7 +145,7 @@ export function useIsEnvironmentAdmin({
|
|||
}
|
||||
|
||||
/**
|
||||
* will return true if the user has the authorizations. assumes the user is authenticated and not an admin
|
||||
* will return true if the user has some of the authorizations. assumes the user is authenticated and not an admin
|
||||
*
|
||||
* @private Please use `useAuthorizations` instead. Exported only for angular's authentication service app/portainer/services/authentication.js:154
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue