From 0dba4f84977904cfd249aa51130d2acb0b692806 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Thu, 19 Nov 2020 15:57:36 -0500 Subject: [PATCH] feat: No auth needed for metadata route and well-known route (#5) --- package.json | 2 +- src/smartHandler.test.ts | 12 ++++++++++++ src/smartHandler.ts | 12 ++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e70bef1..4387333 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "lint-fix": "eslint --fix . --ext .ts,.tsx", "build": "tsc", "watch": "tsc -w", - "test": "jest --silent --passWithNoTests", + "test": "jest --silent", "test-coverage": "jest --coverage", "release": "yarn run build && yarn run lint && yarn run test", "clean": "rm -rf build/* node_modules/* dist/* .serverless/* .nyc_output/* lib/*", diff --git a/src/smartHandler.test.ts b/src/smartHandler.test.ts index 13c4ccc..cd0ebb8 100644 --- a/src/smartHandler.test.ts +++ b/src/smartHandler.test.ts @@ -164,6 +164,17 @@ describe('verifyAccessToken; scopes are in an array', () => { }); }); +describe('verifyAccessToken; metadata and well-known route', () => { + const cases = [ + ['metadata', { accessToken: '', operation: 'read', resourceType: 'metadata' }], + ['well-known', { accessToken: '', operation: 'read', resourceType: '.well-known' }], + ]; + const authZHandler: SMARTHandler = new SMARTHandler(authZConfig); + test.each(cases)('CASE: %p', async (_firstArg, request) => { + expect(authZHandler.verifyAccessToken(request as VerifyAccessTokenRequest)).resolves.toEqual({}); + }); +}); + const spaceScopesCases: (string | boolean | VerifyAccessTokenRequest)[][] = [ [ 'manyRead_Write', @@ -266,6 +277,7 @@ const apiCases: (string | boolean | VerifyAccessTokenRequest | number | any)[][] false, ], ]; + describe("verifyAccessToken; AuthZ's userInfo interactions", () => { const authZHandler: SMARTHandler = new SMARTHandler(authZConfig); test.each(apiCases)('CASE: %p', async (_firstArg, request, authRespCode, authRespBody, isValid) => { diff --git a/src/smartHandler.ts b/src/smartHandler.ts index 613c17c..0ae4aad 100644 --- a/src/smartHandler.ts +++ b/src/smartHandler.ts @@ -15,6 +15,7 @@ import { WriteRequestAuthorizedRequest, AccessBulkDataJobRequest, R4_PATIENT_COMPARTMENT_RESOURCES, + KeyValueMap, } from 'fhir-works-on-aws-interface'; import axios from 'axios'; import { LaunchType, ScopeType, SMARTConfig } from './smartConfig'; @@ -36,7 +37,14 @@ export class SMARTHandler implements Authorization { this.config = config; } - async verifyAccessToken(request: VerifyAccessTokenRequest) { + async verifyAccessToken(request: VerifyAccessTokenRequest): Promise { + if ( + request.operation === 'read' && + (request.resourceType === 'metadata' || request.resourceType === '.well-known') + ) { + return {}; + } + // The access_token will be verified by hitting the authZUserInfoUrl (token introspection) // Decoding first to determine if it passes scope & claims check first const decoded = decode(request.accessToken, { json: true }) || {}; @@ -58,7 +66,7 @@ export class SMARTHandler implements Authorization { } if (!this.areScopesSufficient(scopes, request.operation, request.resourceType)) { console.error( - `User supplied scopes are insuffiecient\nscopes: ${scopes}\noperation: ${request.operation}\nresourceType: ${request.resourceType}`, + `User supplied scopes are insufficient\nscopes: ${scopes}\noperation: ${request.operation}\nresourceType: ${request.resourceType}`, ); throw new UnauthorizedError('User does not have permission for requested operation'); }