Skip to content

Commit

Permalink
feat: implement guest user permission check and restrict access
Browse files Browse the repository at this point in the history
  • Loading branch information
samshara committed Aug 7, 2024
1 parent c1cb0f9 commit b6bd6aa
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changeset/orange-seas-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"go-web-app": minor
---

Implement Guest User Permission in [#1237](https://github.com/IFRCGo/go-web-app/issues/1237)
1 change: 1 addition & 0 deletions app/src/App/routes/CountryRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ const perExport = customWrapRoute({
context: {
title: 'PER Export',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down
1 change: 1 addition & 0 deletions app/src/App/routes/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Perms {
isPerAdmin: boolean,
isIfrcAdmin: boolean,
isSuperUser: boolean,
isGuestUser: boolean,
}

export type ExtendedProps = {
Expand Down
40 changes: 33 additions & 7 deletions app/src/App/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ const newThreeWProject = customWrapRoute({
context: {
title: 'New 3W Project',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -451,6 +452,7 @@ const threeWProjectEdit = customWrapRoute({
context: {
title: 'Edit 3W Project',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -465,6 +467,7 @@ const newThreeWActivity = customWrapRoute({
context: {
title: 'New 3W Activity',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -493,6 +496,7 @@ const threeWActivityEdit = customWrapRoute({
context: {
title: 'Edit 3W Activity',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -620,6 +624,7 @@ const accountMyFormsLayout = customWrapRoute({
context: {
title: 'Account - My Forms',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -650,6 +655,7 @@ const accountMyFormsFieldReport = customWrapRoute({
context: {
title: 'Account - Field Report Forms',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -663,6 +669,7 @@ const accountMyFormsPer = customWrapRoute({
context: {
title: 'Account - PER Forms',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -676,6 +683,7 @@ const accountMyFormsDref = customWrapRoute({
context: {
title: 'Account - DREF Applications',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -689,6 +697,7 @@ const accountMyFormsThreeW = customWrapRoute({
context: {
title: 'Account - 3W',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -799,7 +808,8 @@ const allFieldReports = customWrapRoute({
wrapperComponent: Auth,
context: {
title: 'All Field Reports',
visibility: 'anything',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -814,7 +824,7 @@ const allFlashUpdates = customWrapRoute({
context: {
title: 'All Flash Updates',
visibility: 'is-authenticated',
permissions: ({ isIfrcAdmin }) => isIfrcAdmin,
permissions: ({ isIfrcAdmin, isGuestUser }) => !isGuestUser && isIfrcAdmin,
},
});

Expand All @@ -829,7 +839,7 @@ const flashUpdateFormNew = customWrapRoute({
context: {
title: 'New Flash Update',
visibility: 'is-authenticated',
permissions: ({ isIfrcAdmin }) => isIfrcAdmin,
permissions: ({ isIfrcAdmin, isGuestUser }) => !isGuestUser && isIfrcAdmin,
},
});

Expand All @@ -844,7 +854,7 @@ const flashUpdateFormEdit = customWrapRoute({
context: {
title: 'Edit Flash Update',
visibility: 'is-authenticated',
permissions: ({ isIfrcAdmin }) => isIfrcAdmin,
permissions: ({ isIfrcAdmin, isGuestUser }) => !isGuestUser && isIfrcAdmin,
},
});

Expand All @@ -860,7 +870,7 @@ const flashUpdateFormDetails = customWrapRoute({
context: {
title: 'Flash Update Details',
visibility: 'anything',
permissions: ({ isIfrcAdmin }) => isIfrcAdmin,
permissions: ({ isIfrcAdmin, isGuestUser }) => !isGuestUser && isIfrcAdmin,
},
});

Expand Down Expand Up @@ -889,6 +899,7 @@ const newDrefApplicationForm = customWrapRoute({
context: {
title: 'New DREF Application Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -903,6 +914,7 @@ const drefApplicationForm = customWrapRoute({
context: {
title: 'Edit DREF Application Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -917,6 +929,7 @@ const drefApplicationExport = customWrapRoute({
context: {
title: 'DREF Application Export',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -931,6 +944,7 @@ const drefOperationalUpdateForm = customWrapRoute({
context: {
title: 'Edit DREF Operational Update Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -945,6 +959,7 @@ const drefOperationalUpdateExport = customWrapRoute({
context: {
title: 'DREF Operational Update Export',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});
const drefFinalReportForm = customWrapRoute({
Expand All @@ -958,6 +973,7 @@ const drefFinalReportForm = customWrapRoute({
context: {
title: 'Edit DREF Final Report Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -972,6 +988,7 @@ const drefFinalReportExport = customWrapRoute({
context: {
title: 'DREF Final Report Export',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -986,6 +1003,7 @@ const fieldReportFormNew = customWrapRoute({
context: {
title: 'New Field Report Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1000,6 +1018,7 @@ const fieldReportFormEdit = customWrapRoute({
context: {
title: 'Edit Field Report Form',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1013,7 +1032,8 @@ const fieldReportDetails = customWrapRoute({
wrapperComponent: Auth,
context: {
title: 'Field Report Details',
visibility: 'anything',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1030,6 +1050,7 @@ const perProcessLayout = customWrapRoute({
context: {
title: 'PER Process',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down Expand Up @@ -1064,7 +1085,8 @@ const newPerOverviewForm = customWrapRoute({
permissions: ({
isSuperUser,
isPerAdmin,
}) => isSuperUser || isPerAdmin,
isGuestUser,
}) => !isGuestUser && (isSuperUser || isPerAdmin),
},
});

Expand All @@ -1079,6 +1101,7 @@ const perOverviewForm = customWrapRoute({
context: {
title: 'Edit PER Overview',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1093,6 +1116,7 @@ const perAssessmentForm = customWrapRoute({
context: {
title: 'Edit PER Assessment',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1107,6 +1131,7 @@ const perPrioritizationForm = customWrapRoute({
context: {
title: 'Edit PER Prioritization',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand All @@ -1121,6 +1146,7 @@ const perWorkPlanForm = customWrapRoute({
context: {
title: 'Edit PER Work Plan',
visibility: 'is-authenticated',
permissions: ({ isGuestUser }) => !isGuestUser,
},
});

Expand Down
3 changes: 3 additions & 0 deletions app/src/hooks/domain/usePermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ function usePermissions() {
const isPerAdmin = (userMe?.is_per_admin_for_countries.length ?? 0) > 0
|| (userMe?.is_admin_for_regions.length ?? 0) > 0;

const isGuestUser = (userMe?.limit_access_to_guest);

return {
isDrefRegionalCoordinator,
isRegionAdmin,
Expand All @@ -36,6 +38,7 @@ function usePermissions() {
isPerAdmin,
isIfrcAdmin: !!userMe?.is_ifrc_admin || !!userMe?.email?.toLowerCase().endsWith('@ifrc.org'),
isSuperUser: !!userMe?.is_superuser,
isGuestUser,
};
},
[userMe],
Expand Down
4 changes: 3 additions & 1 deletion app/src/views/Country/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { adminUrl } from '#config';
import RouteContext from '#contexts/route';
import useAuth from '#hooks/domain/useAuth';
import useCountry from '#hooks/domain/useCountry';
import usePermissions from '#hooks/domain/usePermissions';
import useRegion from '#hooks/domain/useRegion';
import {
countryIdToRegionIdMap,
Expand Down Expand Up @@ -67,6 +68,7 @@ export function Component() {
});

const { isAuthenticated } = useAuth();
const { isGuestUser } = usePermissions();

const outletContext = useMemo<CountryOutletContext>(
() => ({
Expand Down Expand Up @@ -180,7 +182,7 @@ export function Component() {
</Link>
)
}
actions={isAuthenticated && (
actions={!isGuestUser && isAuthenticated && (
<Link
external
href={resolveUrl(adminUrl, `api/country/${countryId}/change/`)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ function LocalUnitsTableActions(props: Props) {
onActionSuccess,
} = props;

const { isCountryAdmin, isSuperUser } = usePermissions();
const { isCountryAdmin, isSuperUser, isGuestUser } = usePermissions();
const strings = useTranslation(i18n);

const hasValidatePermission = isSuperUser || isCountryAdmin(countryId);
const hasValidatePermission = !isGuestUser && (isSuperUser || isCountryAdmin(countryId));

const [showLocalUnitViewModal, {
setTrue: setShowLocalUnitViewModalTrue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function NationalSocietyLocalUnits(props: Props) {
const [activeTab, setActiveTab] = useState<'map'| 'table'>('map');
const { isAuthenticated } = useAuth();
const { countryResponse } = useOutletContext<CountryOutletContext>();
const { isSuperUser, isCountryAdmin } = usePermissions();
const { isSuperUser, isCountryAdmin, isGuestUser } = usePermissions();
const containerRef = useRef<HTMLDivElement>(null);

// NOTE: key is used to refresh the page when local unit data is updated
Expand Down Expand Up @@ -111,7 +111,8 @@ function NationalSocietyLocalUnits(props: Props) {

const strings = useTranslation(i18n);

const hasAddLocalUnitPermission = isCountryAdmin(countryResponse?.id) || isSuperUser;
const hasAddLocalUnitPermission = !isGuestUser
&& (isCountryAdmin(countryResponse?.id) || isSuperUser);

useEffect(() => {
document.addEventListener('fullscreenchange', handleFullScreenChange);
Expand Down
4 changes: 3 additions & 1 deletion app/src/views/CountryOngoingActivitiesEmergencies/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import WikiLink from '#components/WikiLink';
import { adminUrl } from '#config';
import useAuth from '#hooks/domain/useAuth';
import useCountryRaw from '#hooks/domain/useCountryRaw';
import usePermissions from '#hooks/domain/usePermissions';
import useFilterState from '#hooks/useFilterState';
import useInputState from '#hooks/useInputState';
import {
Expand Down Expand Up @@ -141,6 +142,7 @@ export function Component(props: BaseProps) {

const strings = useTranslation(i18n);
const { isAuthenticated } = useAuth();
const { isGuestUser } = usePermissions();

const {
countryId,
Expand Down Expand Up @@ -460,7 +462,7 @@ export function Component(props: BaseProps) {
return (
<Container
className={styles.countryOngoingActivities}
actions={isAuthenticated && (
actions={!isGuestUser && isAuthenticated && (
<>
<Link
external
Expand Down
9 changes: 7 additions & 2 deletions app/src/views/CountryPreparedness/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ import PublicCountryPreparedness from './PublicCountryPreparedness';
// eslint-disable-next-line import/prefer-default-export
export function Component() {
const { countryId } = useParams<{ perId: string, countryId: string }>();
const { isCountryPerAdmin, isSuperUser, isRegionPerAdmin } = usePermissions();
const {
isCountryPerAdmin,
isSuperUser,
isRegionPerAdmin,
isGuestUser,
} = usePermissions();

const countryDetails = useCountry({ id: Number(countryId) });

const hasPermission = (
const hasPermission = !isGuestUser && (
isSuperUser
|| isCountryPerAdmin(Number(countryId))
|| isRegionPerAdmin(Number(countryDetails?.region))
Expand Down

0 comments on commit b6bd6aa

Please sign in to comment.