Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/devsu 2269 update access checks #463

Merged
merged 29 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0ac4e79
add access types and use in report context
elewis2 May 6, 2024
59f5ee1
move vars around; add check to reportview
elewis2 May 6, 2024
8d5b6f7
restrict displayed groups to core
elewis2 May 6, 2024
5a62ea8
use lowercase group names
elewis2 May 6, 2024
22a52f8
restrict group editing to userlist
elewis2 May 7, 2024
d074500
remove isExternal checks
elewis2 May 7, 2024
d52496f
cleanup
elewis2 May 7, 2024
4033726
remove inserted char
elewis2 May 7, 2024
2a6f063
Merge branch 'develop' into feat/DEVSU-2269-update-access-checks
elewis2 May 8, 2024
fc29a56
Merge branch 'develop' of https://github.com/bcgsc/pori_ipr_client in…
elewis2 May 8, 2024
a1f7da0
add isManager access checks
elewis2 May 9, 2024
b217228
Merge branch 'develop' into feat/DEVSU-2269-update-access-checks
bnguyen-bcgsc May 9, 2024
4a13326
Merge branch 'develop' of https://github.com/bcgsc/pori_ipr_client in…
elewis2 May 15, 2024
60087c8
add api error details to display
elewis2 May 15, 2024
a605c7b
update manager view of projects
elewis2 May 16, 2024
c990155
add todo
elewis2 May 16, 2024
1ca564e
Merge branch 'develop' into feat/DEVSU-2269-update-access-checks
elewis2 May 16, 2024
fa639ae
Merge branch 'feat/DEVSU-2269-update-access-checks' of https://github…
elewis2 May 16, 2024
da9d248
allow managers to edit proejct desc
elewis2 May 16, 2024
268f951
fix sidebar test
elewis2 May 16, 2024
427a5cd
change groups to lowercase and removes old groups
elewis2 May 16, 2024
5ab9857
Merge branch 'develop' of https://github.com/bcgsc/pori_ipr_client in…
elewis2 May 16, 2024
ac5984e
Merge branch 'develop' into feat/DEVSU-2269-update-access-checks
elewis2 May 16, 2024
e1beae8
Merge branch 'develop' into feat/DEVSU-2269-update-access-checks
bnguyen-bcgsc May 16, 2024
fabd23f
pr fixes
elewis2 May 16, 2024
732fdee
remove unused import
elewis2 May 16, 2024
f2ef8ca
Merge branch 'feat/DEVSU-2269-update-access-checks' of https://github…
elewis2 May 16, 2024
25ca7ea
pr fixes
elewis2 May 16, 2024
b03b323
pr fix
elewis2 May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions app/components/AuthenticatedRoute/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import { isAuthorized } from '@/services/management/auth';
* @returns {Route} a route component which checks authorization on render or redirects to login
*/
const AuthenticatedRoute = ({
component: Component, adminRequired, showNav, onToggleNav, ...rest
component: Component, managerRequired, showNav, onToggleNav, ...rest
}) => {
const { authorizationToken } = useSecurity();
const { adminAccess } = useResource();
const { managerAccess, adminAccess } = useResource();
const authOk = isAuthorized(authorizationToken);

const ChildComponent = useMemo(() => {
Expand All @@ -34,13 +34,13 @@ const AuthenticatedRoute = ({
};
}

if (!adminAccess && adminRequired) {
if (!managerAccess && managerRequired) {
return () => (
<Redirect to="/" />
);
}
return Component;
}, [Component, adminAccess, adminRequired, authOk]);
}, [Component, adminAccess, managerAccess, managerRequired, authOk]);

if (showNav) {
onToggleNav(true);
Expand All @@ -57,7 +57,7 @@ const AuthenticatedRoute = ({
};

AuthenticatedRoute.propTypes = {
adminRequired: PropTypes.bool,
managerRequired: PropTypes.bool,
// eslint-disable-next-line react/forbid-prop-types
component: PropTypes.object.isRequired,
// eslint-disable-next-line react/forbid-prop-types
Expand All @@ -67,7 +67,7 @@ AuthenticatedRoute.propTypes = {
};

AuthenticatedRoute.defaultProps = {
adminRequired: false,
managerRequired: false,
location: null,
onToggleNav: () => {},
showNav: false,
Expand Down
7 changes: 7 additions & 0 deletions app/components/Sidebar/__tests__/Sidebar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ const permissions = {
reportsAccess: true,
adminAccess: true,
reportSettingAccess: true,
managerAccess: false,
reportEditAccess: false,
unreviewedAccess: false,
nonproductionAccess: false,
allStates: [],
unreviewedStates: [],
nonproductionStates: [],
};

const theme = createTheme();
Expand Down
8 changes: 4 additions & 4 deletions app/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import './index.scss';
const Sidebar = (): JSX.Element => {
const { pathname } = useLocation();
const { sidebarMaximized, setSidebarMaximized } = useContext(SidebarContext);
const { germlineAccess, reportsAccess, adminAccess } = useResource();
const { germlineAccess, reportsAccess, managerAccess, adminAccess } = useResource();

const handleSidebarClose = useCallback(() => {
setSidebarMaximized(false);
Expand All @@ -42,7 +42,7 @@ const Sidebar = (): JSX.Element => {
const drawer = useMemo(() => {
let adminSection = null;

if (adminAccess) {
if (managerAccess || adminAccess) {
adminSection = (
<>
<ListItem
Expand Down Expand Up @@ -129,7 +129,7 @@ const Sidebar = (): JSX.Element => {
</ListItem>
</>
);
} else if (!adminAccess && reportsAccess) {
} else if (!managerAccess && reportsAccess) {
adminSection = (
<ListItem
className={`
Expand Down Expand Up @@ -233,7 +233,7 @@ const Sidebar = (): JSX.Element => {
</List>
</div>
);
}, [adminAccess, germlineAccess, handleSidebarClose, pathname, reportsAccess, sidebarMaximized]);
}, [adminAccess, managerAccess, germlineAccess, handleSidebarClose, pathname, reportsAccess, sidebarMaximized]);

let drawerProps: DrawerProps = {
variant: 'temporary',
Expand Down
60 changes: 57 additions & 3 deletions app/context/ResourceContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,21 @@ import { checkAccess, ALL_ROLES } from '@/utils/checkAccess';
import useSecurity from '@/hooks/useSecurity';
import ResourceContextType from './types';

const GERMLINE_ACCESS = ['admin', 'analyst', 'bioinformatician', 'projects', 'manager'];
// TODO: determine whether bioinformaticians need nonprod or germline access;
// determine whether report managers do
// TODO: rename bioinformatician role?
const GERMLINE_ACCESS = ['admin', 'manager', 'bioinformatician', 'germline access'];
const UNREVIEWED_ACCESS = ['admin', 'manager', 'report manager', 'bioinformatician', 'unreviewed access'];
const NONPRODUCTION_ACCESS = ['admin', 'manager', 'bioinformatician', 'non-production access'];

const GERMLINE_BLOCK = ALL_ROLES;
const UNREVIEWED_ACCESS_BLOCK = [];
const NONPRODUCTION_ACCESS_BLOCK = [];

const ALL_STATES = ['signedoff', 'nonproduction', 'uploaded', 'reviewed', 'completed', 'ready', 'active'];
const UNREVIEWED_STATES = ['uploaded', 'ready', 'active']; // TODO decide if nonproduction should go in unreviewed as well
const NONPRODUCTION_STATES = ['nonproduction'];

const REPORTS_ACCESS = ['*'];
const REPORTS_BLOCK = [];
const ADMIN_ACCESS = ['admin'];
Expand All @@ -19,7 +32,10 @@ const useResources = (): ResourceContextType => {
const [reportsAccess, setReportsAccess] = useState(false);
const [reportEditAccess, setReportEditAccess] = useState(false);
const [adminAccess, setAdminAccess] = useState(false);
const [managerAccess, setManagerAccess] = useState(false);
const [reportSettingAccess, setReportSettingAccess] = useState(false);
const [unreviewedAccess, setUnreviewedAccess] = useState(false);
const [nonproductionAccess, setNonproductionAccess] = useState(false);

// Check user group first to see which resources they can access
useEffect(() => {
Expand All @@ -36,28 +52,51 @@ const useResources = (): ResourceContextType => {
setAdminAccess(true);
}

if (checkAccess(groups, [...ADMIN_ACCESS, 'manager', 'Report Manager'], ADMIN_BLOCK)) {
if (checkAccess(groups, [...ADMIN_ACCESS, 'manager'], ADMIN_BLOCK)) {
setManagerAccess(true);
}

if (checkAccess(groups, [...ADMIN_ACCESS, 'manager', 'report manager'], ADMIN_BLOCK)) {
setReportSettingAccess(true);
setReportEditAccess(true);
}
if (checkAccess(groups, UNREVIEWED_ACCESS, UNREVIEWED_ACCESS_BLOCK)) {
setUnreviewedAccess(true);
}
if (checkAccess(groups, NONPRODUCTION_ACCESS, NONPRODUCTION_ACCESS_BLOCK)) {
setNonproductionAccess(true);
}

}
}, [groups]);

return {
germlineAccess,
reportsAccess,
adminAccess,
managerAccess,
reportSettingAccess,
reportEditAccess,
unreviewedAccess,
nonproductionAccess,
allStates: ALL_STATES,
unreviewedStates: UNREVIEWED_STATES,
nonproductionStates: NONPRODUCTION_STATES,
};
};

const ResourceContext = createContext<ResourceContextType>({
germlineAccess: false,
reportsAccess: false,
adminAccess: false,
managerAccess: false,
reportSettingAccess: false,
reportEditAccess: false,
unreviewedAccess: false,
nonproductionAccess: false,
allStates: ALL_STATES,
unreviewedStates: UNREVIEWED_STATES,
nonproductionStates: NONPRODUCTION_STATES,
});

type ResourceContextProviderProps = {
Expand All @@ -66,21 +105,36 @@ type ResourceContextProviderProps = {

const ResourceContextProvider = ({ children }: ResourceContextProviderProps): JSX.Element => {
const {
germlineAccess, reportsAccess, adminAccess, reportSettingAccess, reportEditAccess,
germlineAccess, reportsAccess, adminAccess, managerAccess, reportSettingAccess, reportEditAccess, unreviewedAccess, nonproductionAccess,
allStates,
unreviewedStates,
nonproductionStates,
} = useResources();

const providerValue = useMemo(() => ({
germlineAccess,
reportsAccess,
adminAccess,
managerAccess,
reportSettingAccess,
reportEditAccess,
unreviewedAccess,
nonproductionAccess,
allStates,
unreviewedStates,
nonproductionStates,
}), [
germlineAccess,
reportsAccess,
adminAccess,
managerAccess,
reportSettingAccess,
reportEditAccess,
unreviewedAccess,
nonproductionAccess,
allStates,
unreviewedStates,
nonproductionStates,
]);

return (
Expand Down
6 changes: 6 additions & 0 deletions app/context/ResourceContext/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ type ResourceContextType = {
germlineAccess: boolean;
reportsAccess: boolean;
adminAccess: boolean;
managerAccess: boolean;
reportSettingAccess: boolean;
reportEditAccess: boolean;
unreviewedAccess: boolean;
nonproductionAccess: boolean;
allStates: string[];
unreviewedStates: string[];
nonproductionStates: string[];
};

export default ResourceContextType;
24 changes: 0 additions & 24 deletions app/hooks/useExternalMode.ts

This file was deleted.

16 changes: 2 additions & 14 deletions app/utils/checkAccess.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
const ALL_ROLES = [
'admin',
'Analyst',
'BioApps',
'Bioinformatician',
'Biopsies',
'Biospecimen Core',
'Clinician',
'Collaborator',
'Demo',
'External Analyst',
'LIMS',
'bioinformatician',
'manager',
'non-production access',
'Pipelines',
'Projects',
'Report Manager',
'Research',
'report manager',
];

/*
Expand Down
2 changes: 1 addition & 1 deletion app/views/AdminView/components/Groups/columnDefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const columnDefs = [
},
{
headerName: 'Owner',
valueGetter: ({ data }) => `${data.owner.firstName} ${data.owner.lastName}`,
valueGetter: ({ data }) => `${data?.owner?.firstName ?? data.owner.username} ${data.owner.lastName ?? ''}`,
hide: false,
},
{
Expand Down
Loading
Loading