forked from openedx/frontend-app-admin-console
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontext.tsx
More file actions
80 lines (67 loc) · 2.48 KB
/
context.tsx
File metadata and controls
80 lines (67 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import {
createContext, useContext, useMemo, ReactNode,
} from 'react';
import { useParams } from 'react-router-dom';
import { AppContext } from '@edx/frontend-platform/react';
import { useValidateUserPermissions } from '@src/data/hooks';
import { usePermissionsByRole } from '@src/authz-module/data/hooks';
import { PermissionMetadata, ResourceMetadata, Role } from 'types';
import { libraryPermissions, libraryResourceTypes, libraryRolesMetadata } from './constants';
const LIBRARY_TEAM_PERMISSIONS = ['view_library_team', 'manage_library_team'];
export type AppContextType = {
authenticatedUser: {
username: string;
email: string;
};
};
type LibraryAuthZContextType = {
canManageTeam: boolean;
username: string;
libraryId: string;
resources: ResourceMetadata[];
roles: Role[];
permissions: PermissionMetadata[];
};
const LibraryAuthZContext = createContext<LibraryAuthZContextType | undefined>(undefined);
type AuthZProviderProps = {
children: ReactNode;
};
export const LibraryAuthZProvider: React.FC<AuthZProviderProps> = ({ children }:AuthZProviderProps) => {
const { libraryId } = useParams<{ libraryId: string }>();
const { authenticatedUser } = useContext(AppContext) as AppContextType;
// TODO: Implement a custom error view
if (!libraryId) {
throw new Error('MissingLibrary');
}
const permissions = LIBRARY_TEAM_PERMISSIONS.map(action => ({ action, scope: libraryId }));
const { data: userPermissions } = useValidateUserPermissions(permissions);
const [{ allowed: canViewTeam }, { allowed: canManageTeam }] = userPermissions;
if (!canViewTeam && !canManageTeam) {
throw new Error('NoAccess');
}
const { data: libraryRoles } = usePermissionsByRole(libraryId);
const roles = libraryRoles.map(role => ({
...role,
...libraryRolesMetadata.find(r => r.role === role.role),
} as Role));
const value = useMemo((): LibraryAuthZContextType => ({
username: authenticatedUser.username,
libraryId,
roles,
permissions: libraryPermissions,
resources: libraryResourceTypes,
canManageTeam,
}), [libraryId, authenticatedUser.username, canManageTeam, roles]);
return (
<LibraryAuthZContext.Provider value={value}>
{children}
</LibraryAuthZContext.Provider>
);
};
export const useLibraryAuthZ = (): LibraryAuthZContextType => {
const context = useContext(LibraryAuthZContext);
if (context === undefined) {
throw new Error('useLibraryAuthZ must be used within an LibraryAuthZProvider');
}
return context;
};