Skip to content

Commit

Permalink
Update PUT user to allow regional admins to update users within their…
Browse files Browse the repository at this point in the history
… region (#686)

* Allow regionalAdmins to update users

* Update so globaladmins without regions aren't blocked

* Add to approve endpoint as well

* MAke matches user region not async

* Fix can access user

* hotfix to resolve issue where regional admin could not approve user from within their region

---------

Co-authored-by: Janson Bunce <[email protected]>
  • Loading branch information
aloftus23 and Janson Bunce authored Oct 10, 2024
1 parent d9a802e commit 7e58cfc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
20 changes: 19 additions & 1 deletion backend/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface UserToken {
org: string;
role: 'user' | 'admin';
}[];
regionId: string | null;
dateAcceptedTerms: Date | undefined;
acceptedTermsVersion: string | undefined;
lastLoggedIn: Date | undefined;
Expand Down Expand Up @@ -95,6 +96,7 @@ export const userTokenBody = (user): UserToken => ({
email: user.email,
userType: user.userType,
dateAcceptedTerms: user.dateAcceptedTerms,
regionId: user.regionId,
acceptedTermsVersion: user.acceptedTermsVersion,
lastLoggedIn: user.lastLoggedIn,
loginBlockedByMaintenance: user.loginBlockedByMaintenance,
Expand Down Expand Up @@ -310,9 +312,25 @@ export const matchesRegion = async (
return regionId === (await getRegion(organizationId));
};

/** Checks if the authorizer's region is the same as the user's being modified */
export const matchesUserRegion = (
event: APIGatewayProxyEvent,
userRegionId?: string
) => {
// Global admins can match with any region
if (isGlobalWriteAdmin(event)) return true;
if (!event.requestContext.authorizer || !userRegionId) return false;
return userRegionId === event.requestContext.authorizer.regionId;
};

/** Checks if the current user is allowed to access (modify) a user with id userId */
export const canAccessUser = (event: APIGatewayProxyEvent, userId?: string) => {
return userId && (userId === getUserId(event) || isGlobalWriteAdmin(event));
return (
userId &&
(userId === getUserId(event) ||
isGlobalWriteAdmin(event) ||
isRegionalAdmin(event))
);
};

/** Checks if a user is an admin of the given organization */
Expand Down
5 changes: 4 additions & 1 deletion backend/src/api/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import {
isRegionalAdmin,
isRegionalAdminForOrganization,
getOrgMemberships,
isGlobalViewAdmin
isGlobalViewAdmin,
matchesUserRegion
} from './auth';
import { In } from 'typeorm';
import { plainToClass } from 'class-transformer';
Expand Down Expand Up @@ -981,6 +982,8 @@ export const addUserV2 = wrapHandler(async (event) => {
// Get User from the database
const user = await User.findOneOrFail(userId);

if (!matchesUserRegion(event, user.regionId)) return Unauthorized;

const newRoleData = {
user: user,
organization: org,
Expand Down
9 changes: 8 additions & 1 deletion backend/src/api/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import {
isGlobalViewAdmin,
isRegionalAdmin,
isOrgAdmin,
isGlobalWriteAdmin
isGlobalWriteAdmin,
matchesUserRegion
} from './auth';
import { fetchAssessmentsByUser } from '../tasks/rscSync';

Expand Down Expand Up @@ -634,6 +635,9 @@ export const registrationApproval = wrapHandler(async (event) => {
return NotFound;
}

// Check if authorizer's region matches the user's
if (!matchesUserRegion(event, user.regionId)) return Unauthorized;

// Send email notification
await sendRegistrationApprovedEmail(
user.email,
Expand Down Expand Up @@ -919,6 +923,9 @@ export const updateV2 = wrapHandler(async (event) => {
return NotFound;
}

// Check if authorizer's region matches the user's
if (!matchesUserRegion(event, user.regionId)) return Unauthorized;

if (body.state) {
body.regionId = REGION_STATE_MAP[body.state];
}
Expand Down

0 comments on commit 7e58cfc

Please sign in to comment.