Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adding handling for multiple identitySource headers in the REST API. #1675

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/events/http/createAuthScheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,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"
}