Skip to content

Commit

Permalink
feat: Adding handling for multiple identitySource headers in the REST…
Browse files Browse the repository at this point in the history
… API. (#1675)

Co-authored-by: Kevin Hankens <kevin-hankens@idexx.com>
  • Loading branch information
kevinhankens and Kevin Hankens committed Sep 25, 2023
1 parent 2081634 commit 6fceed3
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/events/http/createAuthScheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
authorizerOptions.type !== 'request' ||
authorizerOptions.identitySource
) {
const headerRegExp = /^(method.|\$)request.header.((?:\w+-?)+\w+)$/
// Only validate the first of N possible headers.
const headerRegExp = /^(method.|\$)request.header.((?:\w+-?)+\w+).*$/
const queryStringRegExp =
/^(method.|\$)request.querystring.((?:\w+-?)+\w+)$/

Expand Down
79 changes: 79 additions & 0 deletions tests/integration/restApi-authorizers/restApi-authorizers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// tests based on:
// https://dev.to/piczmar_0/serverless-authorizers---custom-rest-authorizer-16

import assert from 'node:assert'
import { join } from 'desm'
import { setup, teardown } from '../../_testHelpers/index.js'
import { BASE_URL } from '../../config.js'

describe('RestApi Authorizers Tests', function desc() {
beforeEach(() =>
setup({
servicePath: join(import.meta.url),
}),
)

afterEach(() => teardown())

it('should handle configuration with a single header in method.request format', async () => {
const url = new URL('/dev/single-header-method', BASE_URL)
const options = {
headers: {
Authorization: 'Bearer abc123',
'Content-Type': 'application/json',
},
method: 'get',
}

const response = await fetch(url, options)

assert.equal(response.status, 200)
})

it('should handle configuration with a multi header in method.request format', async () => {
const url = new URL('/dev/multi-header-method', BASE_URL)
const options = {
headers: {
Authorization: 'Bearer abc123',
'Content-Type': 'application/json',
UserId: 'xxx',
},
method: 'get',
}

const response = await fetch(url, options)

assert.equal(response.status, 200)
})

it('should handle configuration with a single header in $request format', async () => {
const url = new URL('/dev/single-header-dollar', BASE_URL)
const options = {
headers: {
Authorization: 'Bearer abc123',
'Content-Type': 'application/json',
},
method: 'get',
}

const response = await fetch(url, options)

assert.equal(response.status, 200)
})

it('should handle configuration with a multi header in $request format', async () => {
const url = new URL('/dev/multi-header-dollar', BASE_URL)
const options = {
headers: {
Authorization: 'Bearer abc123',
'Content-Type': 'application/json',
UserId: 'xxx',
},
method: 'get',
}

const response = await fetch(url, options)

assert.equal(response.status, 200)
})
})
62 changes: 62 additions & 0 deletions tests/integration/restApi-authorizers/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
service: restapi-authorizers

configValidationMode: error
deprecationNotificationMode: error

plugins:
- ../../../src/index.js

provider:
architecture: arm64
deploymentMethod: direct
memorySize: 1024
name: aws
region: us-east-1
runtime: nodejs18.x
stage: dev
versionFunctions: false

functions:
restapi-authorizers:
events:
- http:
integration: lambda
method: get
path: single-header-method
authorizer:
name: authorizer-single-header
type: request
resultTtlInSeconds: 3600
identitySource: method.request.header.Authorization
- http:
integration: lambda
method: get
path: multi-header-method
authorizer:
name: authorizer-multi-header
type: request
resultTtlInSeconds: 3600
identitySource: method.request.header.Authorization, method.request.header.UserId
- http:
integration: lambda
method: get
path: single-header-dollar
authorizer:
name: authorizer-single-header
type: request
resultTtlInSeconds: 3600
identitySource: $request.header.Authorization
- http:
integration: lambda
method: get
path: multi-header-dollar
authorizer:
name: authorizer-multi-header
type: request
resultTtlInSeconds: 3600
identitySource: $request.header.Authorization, $request.header.UserId
handler: src/handler.test
authorizer-single-header:
handler: src/handler.authorizerSingle
authorizer-multi-header:
handler: src/handler.authorizerMulti
41 changes: 41 additions & 0 deletions tests/integration/restApi-authorizers/src/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { stringify } = JSON

export const test = async () => {
return {
body: stringify({
foo: 'bar',
}),
statusCode: 200,
}
}

function generatePolicy(principalId, effect, resource, context) {
const authResponse = {
context,
principalId,
}

if (effect && resource) {
const policyDocument = {
Statement: [
{
Action: 'execute-api:Invoke',
Effect: effect,
Resource: resource,
},
],
Version: '2012-10-17',
}

authResponse.policyDocument = policyDocument
}
return authResponse
}

export const authorizerSingle = async (event) => {
return generatePolicy('user123', 'Allow', event.methodArn, {})
}

export const authorizerMulti = async (event) => {
return generatePolicy('user123', 'Allow', event.methodArn, {})
}
3 changes: 3 additions & 0 deletions tests/integration/restApi-authorizers/src/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}

0 comments on commit 6fceed3

Please sign in to comment.