Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,25 @@ import { buildResponse } from '@easy-genomics/shared-lib/src/app/utils/common';
import { APIGatewayProxyResult, APIGatewayProxyWithCognitoAuthorizerEvent, Handler } from 'aws-lambda';
import { v4 as uuidv4 } from 'uuid';
import { OrganizationService } from '@BE/services/easy-genomics/organization-service';
import { validateSystemAdminAccess } from '@BE/utils/auth-utils';

const organizationService = new OrganizationService();

/**
* This API is restricted to only the System Admin User who will oversee the
* creation of one or more Organizations in the Easy Genomics platform.
*
* @param event
*/
export const handler: Handler = async (
event: APIGatewayProxyWithCognitoAuthorizerEvent,
): Promise<APIGatewayProxyResult> => {
console.log('EVENT: \n' + JSON.stringify(event, null, 2));
try {
const userId = event.requestContext.authorizer.claims['cognito:username'];
if (!validateSystemAdminAccess(event)) {
throw new Error('Unauthorized access');
}
// Post Request Body
const request: Organization = event.isBase64Encoded ? JSON.parse(atob(event.body!)) : JSON.parse(event.body!);
// Data validation safety check
Expand Down
61 changes: 61 additions & 0 deletions packages/back-end/src/app/utils/auth-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
LaboratoryAccess,
LaboratoryAccessDetails,
OrganizationAccess,
OrganizationAccessDetails,
} from '@easy-genomics/shared-lib/src/app/types/easy-genomics/user';
import { APIGatewayProxyWithCognitoAuthorizerEvent } from 'aws-lambda';
import { APIGatewayProxyEvent } from 'aws-lambda/trigger/api-gateway-proxy';

/**
* Helper function to check if the current User's Cognito session belongs to
* System Admin user in order to allow access to restricted APIs.
* @param event
*/
export function validateSystemAdminAccess(event: APIGatewayProxyWithCognitoAuthorizerEvent): Boolean {
const cognitoGroup: string = event.requestContext.authorizer.claims['cognito:groups'];
return cognitoGroup === 'SystemAdmin';
}

/**
* Helper function to check if an authenticated User's JWT OrganizationAccess
* metadata allows access to the requested Organization / Laboratory.
* @param event
* @param organizationId
* @param laboratoryId
*/
export function validateOrganizationAccess(
event: APIGatewayProxyEvent,
organizationId: string,
laboratoryId?: string,
): Boolean {
try {
const orgAccessMetadata: string | undefined = event.requestContext.authorizer?.claims.OrganizationAccess;
if (!orgAccessMetadata) {
return false;
}

const organizationAccess: OrganizationAccess = JSON.parse(orgAccessMetadata);
const organizationAccessDetails: OrganizationAccessDetails | undefined = organizationAccess[organizationId];
if (!organizationAccessDetails || (organizationAccessDetails && organizationAccessDetails.Status !== 'Active')) {
return false;
}

if (laboratoryId) {
const laboratoryAccess: LaboratoryAccess | undefined = organizationAccessDetails.LaboratoryAccess;
if (!laboratoryAccess) {
return false;
}

const laboratoryAccessDetails: LaboratoryAccessDetails | undefined = laboratoryAccess[laboratoryId];
if (!laboratoryAccessDetails || (laboratoryAccessDetails && laboratoryAccessDetails.Status !== 'Active')) {
return false;
}
}

return true;
} catch (error) {
console.error(error);
return false;
}
}
49 changes: 0 additions & 49 deletions packages/back-end/src/app/utils/rest-api-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import {
LaboratoryAccess,
LaboratoryAccessDetails,
OrganizationAccess,
OrganizationAccessDetails,
} from '@easy-genomics/shared-lib/src/app/types/easy-genomics/user';
import { APIGatewayProxyEvent } from 'aws-lambda/trigger/api-gateway-proxy';

export const enum REST_API_METHOD {
Expand Down Expand Up @@ -81,46 +75,3 @@ export function getApiParameters(event: APIGatewayProxyEvent): URLSearchParams {

return parameters;
}

/**
* Helper function to check if an authenticated User's JWT OrganizationAccess
* metadata allows access to the requested Organization / Laboratory.
* @param event
* @param organizationId
* @param laboratoryId
*/
export function validateOrganizationAccess(
event: APIGatewayProxyEvent,
organizationId: string,
laboratoryId?: string,
): Boolean {
try {
const orgAccessMetadata: string | undefined = event.requestContext.authorizer?.claims.OrganizationAccess;
if (!orgAccessMetadata) {
return false;
}

const organizationAccess: OrganizationAccess = JSON.parse(orgAccessMetadata);
const organizationAccessDetails: OrganizationAccessDetails | undefined = organizationAccess[organizationId];
if (!organizationAccessDetails || (organizationAccessDetails && organizationAccessDetails.Status !== 'Active')) {
return false;
}

if (laboratoryId) {
const laboratoryAccess: LaboratoryAccess | undefined = organizationAccessDetails.LaboratoryAccess;
if (!laboratoryAccess) {
return false;
}

const laboratoryAccessDetails: LaboratoryAccessDetails | undefined = laboratoryAccess[laboratoryId];
if (!laboratoryAccessDetails || (laboratoryAccessDetails && laboratoryAccessDetails.Status !== 'Active')) {
return false;
}
}

return true;
} catch (error) {
console.error(error);
return false;
}
}