Skip to content

Commit

Permalink
task: Use fine-grained project permissions in frontend (#5974)
Browse files Browse the repository at this point in the history
Connected to [#5932](#5932) -
This starts using the new permissions in addition to the old
UPDATE_PROJECT permission. That way, if you're happy with
UPDATE_PROJECT, you don't need to change.

However, you can now add more fine grained permissions for both READ and
WRITE operations.
  • Loading branch information
Christopher Kolstad committed Jan 22, 2024
1 parent b7483e8 commit 8256c2e
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 19 deletions.
Expand Up @@ -8,7 +8,7 @@ import {
} from 'hooks/useHasAccess';

interface IPermissionSwitchProps extends SwitchProps {
permission: string;
permission: string | string[];
tooltip?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
disabled?: boolean;
Expand Down
Expand Up @@ -4,7 +4,10 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { Alert } from '@mui/material';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import AccessContext from 'contexts/AccessContext';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_CHANGE_REQUEST_READ,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { usePageTitle } from 'hooks/usePageTitle';
import { useProjectNameOrId } from 'hooks/api/getters/useProject/useProject';
Expand Down Expand Up @@ -36,7 +39,7 @@ export const ChangeRequestConfiguration = () => {
);
}

if (!hasAccess(UPDATE_PROJECT, projectId)) {
if (!hasAccess([UPDATE_PROJECT, PROJECT_CHANGE_REQUEST_READ], projectId)) {
return (
<PageContent
header={<PageHeader title='Change request configuration' />}
Expand Down
Expand Up @@ -30,6 +30,7 @@ import { KeyboardArrowDownOutlined } from '@mui/icons-material';
import { useTheme } from '@mui/material/styles';
import AccessContext from 'contexts/AccessContext';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { PROJECT_CHANGE_REQUEST_WRITE } from '../../../../providers/AccessProvider/permissions';

const StyledBox = styled(Box)(({ theme }) => ({
padding: theme.spacing(1),
Expand Down Expand Up @@ -159,7 +160,10 @@ export const ChangeRequestTable: VFC = () => {
}}
disabled={
!hasAccess(
UPDATE_PROJECT,
[
UPDATE_PROJECT,
PROJECT_CHANGE_REQUEST_WRITE,
],
projectId,
)
}
Expand Down Expand Up @@ -188,7 +192,10 @@ export const ChangeRequestTable: VFC = () => {
<PermissionSwitch
checked={value}
projectId={projectId}
permission={UPDATE_PROJECT}
permission={[
UPDATE_PROJECT,
PROJECT_CHANGE_REQUEST_WRITE,
]}
inputProps={{ 'aria-label': original.environment }}
onClick={onRowChange(
original.environment,
Expand Down
Expand Up @@ -4,7 +4,10 @@ import AccessContext from 'contexts/AccessContext';
import { usePageTitle } from 'hooks/usePageTitle';
import { PageContent } from 'component/common/PageContent/PageContent';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_DEFAULT_STRATEGY_READ,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import { Alert, styled } from '@mui/material';
import ProjectEnvironment from './ProjectEnvironment/ProjectEnvironment';
import { Route, Routes, useNavigate } from 'react-router-dom';
Expand All @@ -25,7 +28,9 @@ export const ProjectDefaultStrategySettings = () => {
const navigate = useNavigate();
usePageTitle(`Project default strategy configuration – ${projectName}`);

if (!hasAccess(UPDATE_PROJECT, projectId)) {
if (
!hasAccess([UPDATE_PROJECT, PROJECT_DEFAULT_STRATEGY_READ], projectId)
) {
return (
<PageContent
header={<PageHeader title='Default Strategy configuration' />}
Expand Down
@@ -1,4 +1,7 @@
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_SETTINGS_WRITE,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import useProject from 'hooks/api/getters/useProject/useProject';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
Expand Down Expand Up @@ -26,7 +29,10 @@ const EditProject = () => {
return null;
}

const accessDeniedAlert = !hasAccess(UPDATE_PROJECT, id) && (
const accessDeniedAlert = !hasAccess(
[UPDATE_PROJECT, PROJECT_SETTINGS_WRITE],
id,
) && (
<Alert severity='error' sx={{ mb: 4 }}>
You do not have the required permissions to edit this project.
</Alert>
Expand Down
@@ -1,7 +1,10 @@
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import ProjectForm from '../../../ProjectForm/ProjectForm';
import PermissionButton from 'component/common/PermissionButton/PermissionButton';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_SETTINGS_WRITE,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import useProjectForm, {
DEFAULT_PROJECT_STICKINESS,
} from '../../../hooks/useProjectForm';
Expand Down Expand Up @@ -138,7 +141,10 @@ export const UpdateProject = ({ project }: IUpdateProject) => {
>
<PermissionButton
type='submit'
permission={UPDATE_PROJECT}
permission={[
UPDATE_PROJECT,
PROJECT_SETTINGS_WRITE,
]}
projectId={projectId}
data-testid={EDIT_PROJECT_BTN}
>
Expand Down
Expand Up @@ -3,7 +3,10 @@ import { PageContent } from 'component/common/PageContent/PageContent';
import { Alert } from '@mui/material';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import AccessContext from 'contexts/AccessContext';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_SETTINGS_READ,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { usePageTitle } from 'hooks/usePageTitle';
import EditProject from './EditProject/EditProject';
Expand All @@ -29,7 +32,7 @@ export const Settings = () => {
);
}

if (!hasAccess(UPDATE_PROJECT, projectId)) {
if (!hasAccess([UPDATE_PROJECT, PROJECT_SETTINGS_READ], projectId)) {
return (
<PageContent header={<PageHeader title='Access' />}>
<Alert severity='error'>
Expand Down
Expand Up @@ -4,7 +4,10 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { Alert } from '@mui/material';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import AccessContext from 'contexts/AccessContext';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_USER_ACCESS_READ,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { usePageTitle } from 'hooks/usePageTitle';
import { ProjectAccessTable } from 'component/project/ProjectAccess/ProjectAccessTable/ProjectAccessTable';
Expand All @@ -29,7 +32,7 @@ export const ProjectAccess = () => {
);
}

if (!hasAccess(UPDATE_PROJECT, projectId)) {
if (!hasAccess([UPDATE_PROJECT, PROJECT_USER_ACCESS_READ], projectId)) {
return (
<PageContent header={<PageHeader title='Access' />}>
<Alert severity='error'>
Expand Down
Expand Up @@ -9,7 +9,10 @@ import useProjectAccess, {
IProjectAccess,
} from 'hooks/api/getters/useProjectAccess/useProjectAccess';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import {
PROJECT_USER_ACCESS_WRITE,
UPDATE_PROJECT,
} from 'component/providers/AccessProvider/permissions';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell';
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
Expand Down Expand Up @@ -212,7 +215,10 @@ export const ProjectAccessTable: VFC = () => {
<PermissionIconButton
data-testid={PA_EDIT_BUTTON_ID}
component={Link}
permission={UPDATE_PROJECT}
permission={[
UPDATE_PROJECT,
PROJECT_USER_ACCESS_WRITE,
]}
projectId={projectId}
to={`edit/${
row.type === ENTITY_TYPE.GROUP
Expand All @@ -231,7 +237,10 @@ export const ProjectAccessTable: VFC = () => {
</PermissionIconButton>
<PermissionIconButton
data-testid={PA_REMOVE_BUTTON_ID}
permission={UPDATE_PROJECT}
permission={[
UPDATE_PROJECT,
PROJECT_USER_ACCESS_WRITE,
]}
projectId={projectId}
onClick={() => {
setSelectedRow(row);
Expand Down Expand Up @@ -411,7 +420,10 @@ export const ProjectAccessTable: VFC = () => {
onClick={() => navigate('create')}
maxWidth='700px'
Icon={Add}
permission={UPDATE_PROJECT}
permission={[
UPDATE_PROJECT,
PROJECT_USER_ACCESS_WRITE,
]}
projectId={projectId}
data-testid={PA_ASSIGN_BUTTON_ID}
>
Expand Down
Expand Up @@ -39,3 +39,12 @@ export const READ_PROJECT_API_TOKEN = 'READ_PROJECT_API_TOKEN';
export const CREATE_PROJECT_API_TOKEN = 'CREATE_PROJECT_API_TOKEN';
export const DELETE_PROJECT_API_TOKEN = 'DELETE_PROJECT_API_TOKEN';
export const UPDATE_PROJECT_SEGMENT = 'UPDATE_PROJECT_SEGMENT';

export const PROJECT_USER_ACCESS_READ = 'PROJECT_USER_ACCESS_READ';
export const PROJECT_DEFAULT_STRATEGY_READ = 'PROJECT_DEFAULT_STRATEGY_READ';
export const PROJECT_CHANGE_REQUEST_READ = 'PROJECT_CHANGE_REQUEST_READ';
export const PROJECT_SETTINGS_READ = 'PROJECT_SETTINGS_READ';
export const PROJECT_USER_ACCESS_WRITE = 'PROJECT_USER_ACCESS_WRITE';
export const PROJECT_DEFAULT_STRATEGY_WRITE = 'PROJECT_DEFAULT_STRATEGY_WRITE';
export const PROJECT_CHANGE_REQUEST_WRITE = 'PROJECT_CHANGE_REQUEST_WRITE';
export const PROJECT_SETTINGS_WRITE = 'PROJECT_SETTINGS_WRITE';

0 comments on commit 8256c2e

Please sign in to comment.