Skip to content

Commit

Permalink
Introduce default permissions #1559 (#1567)
Browse files Browse the repository at this point in the history
* Introduce default permissions #1559

* Fixes checking permission after implemented api
  • Loading branch information
olgenn authored Aug 21, 2024
1 parent a627f9a commit 5e1bcba
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 5,479 deletions.
14 changes: 11 additions & 3 deletions frontend/src/hooks/usePermissionGuard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import { selectUserData } from 'App/slice';

import useAppSelector from './useAppSelector';

import { GlobalUserRole, ProjectUserRole } from '../types';
import { GlobalUserRole, ProjectUserRole, UserPermission } from '../types';

interface Args {
allowedGlobalRoles?: GlobalUserRole[];
allowedProjectRoles?: ProjectUserRole[];
allowedPermissions?: UserPermission[];
projectRole?: string;
}
export const usePermissionGuard = ({ allowedGlobalRoles, allowedProjectRoles, projectRole }: Args) => {
export const usePermissionGuard = ({ allowedGlobalRoles, allowedProjectRoles, allowedPermissions, projectRole }: Args) => {
const userData = useAppSelector(selectUserData);
const userGlobalRole = userData?.global_role ?? '';
const userPermissions = userData?.permissions ?? [];

const isAvailableForGlobalUser = useMemo(() => {
if (!allowedGlobalRoles?.length) return false;
Expand All @@ -27,7 +29,13 @@ export const usePermissionGuard = ({ allowedGlobalRoles, allowedProjectRoles, pr
return allowedProjectRoles.includes(projectRole as ProjectUserRole);
}, [allowedGlobalRoles, userGlobalRole]);

const isAvailableContent = isAvailableForGlobalUser || isAvailableForProjectUser;
const hasPermission = useMemo(() => {
if (!allowedPermissions?.length) return false;

return userPermissions.some((userPermission) => allowedPermissions.includes(userPermission as UserPermission));
}, [allowedGlobalRoles, userGlobalRole]);

const isAvailableContent = isAvailableForGlobalUser || isAvailableForProjectUser || hasPermission;

return [isAvailableContent] as const;
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { useAppSelector, usePermissionGuard } from 'hooks';
import { UserPermission } from 'types';

import { selectUserData } from 'App/slice';

import { getProjectRoleByUserName } from '../utils';

import { GlobalUserRole } from '../../../types';

export const useCheckAvailableProjectPermission = () => {
const userData = useAppSelector(selectUserData);
const userName = userData?.username ?? '';
const userGlobalRole = userData?.global_role ?? '';
const [isGlobalAdmin] = usePermissionGuard({ allowedGlobalRoles: [GlobalUserRole.ADMIN] });

const [hasPermissionForProjectManaging] = usePermissionGuard({
allowedPermissions: [UserPermission.CAN_CREATE_PROJECTS],
});

const isAvailableDeletingPermission = (project: IProject): boolean => {
return getProjectRoleByUserName(project, userName) === 'admin' || userGlobalRole === 'admin';
Expand All @@ -28,8 +30,7 @@ export const useCheckAvailableProjectPermission = () => {
return isProjectAdmin(project) || getProjectRoleByUserName(project, userName) === 'manager';
};

const isAvailableProjectManaging =
(isGlobalAdmin && process.env.UI_VERSION === 'enterprise') || process.env.UI_VERSION === 'sky';
const isAvailableProjectManaging = hasPermissionForProjectManaging;

return {
isAvailableDeletingPermission,
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/services/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { fetchBaseQuery } from '@reduxjs/toolkit/query/react';

import fetchBaseQueryHeaders from 'libs/fetchBaseQueryHeaders';

import { UserPermission, userPermissionMap } from '../types';

export const userApi = createApi({
reducerPath: 'userApi',
refetchOnMountOrArgChange: true,
Expand All @@ -21,6 +23,19 @@ export const userApi = createApi({
method: 'POST',
};
},

transformResponse: (userData: IUserResponseData): IUser => {
return {
...userData,
permissions: Object.keys(userPermissionMap).reduce<TUserPermission[]>((acc, key) => {
if (userData?.permissions?.[key as TUserPermissionKeys]) {
acc.push(UserPermission[userPermissionMap[key as TUserPermissionKeys]]);
}

return acc;
}, []),
};
},
}),

getUserList: builder.query<IUser[], void>({
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ export enum ProjectUserRole {
USER = 'user',
MANAGER = 'manager'
}

export enum UserPermission {
CAN_CREATE_PROJECTS = 'CAN_CREATE_PROJECTS',
}

export const userPermissionMap: Record<TUserPermissionKeys, UserPermission> = {
'can_create_projects': UserPermission.CAN_CREATE_PROJECTS
}


Loading

0 comments on commit 5e1bcba

Please sign in to comment.