Skip to content

Commit

Permalink
apigatewayv2: lambda authorizer
Browse files Browse the repository at this point in the history
  • Loading branch information
fwang committed Sep 3, 2024
1 parent 15e7dc4 commit 6d6a782
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 57 deletions.
2 changes: 1 addition & 1 deletion platform/src/components/aws/apigatewayv1-authorizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class ApiGatewayV1Authorizer extends Component {
type,
name: args.name,
providerArns: args.userPools,
authorizerUri: fn?.nodes.function.invokeArn,
authorizerUri: fn!.nodes.function.invokeArn,
authorizerResultTtlInSeconds: args.ttl,
identitySource: args.identitySource,
},
Expand Down
100 changes: 87 additions & 13 deletions platform/src/components/aws/apigatewayv2-authorizer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { ComponentResourceOptions, Input, output } from "@pulumi/pulumi";
import {
ComponentResourceOptions,
Input,
interpolate,
output,
} from "@pulumi/pulumi";
import { Component, transform } from "../component";
import { ApiGatewayV2AuthorizerArgs } from "./apigatewayv2";
import { apigatewayv2 } from "@pulumi/aws";
import { apigatewayv2, lambda } from "@pulumi/aws";
import { VisibleError } from "../error";
import { toSeconds } from "../duration";
import { Function } from "./function";

export interface AuthorizerArgs extends ApiGatewayV2AuthorizerArgs {
/**
Expand All @@ -16,6 +24,10 @@ export interface AuthorizerArgs extends ApiGatewayV2AuthorizerArgs {
* The ID of the API Gateway.
*/
id: Input<string>;
/**
* The execution ARN of the API Gateway.
*/
executionArn: Input<string>;
}>;
}

Expand All @@ -42,34 +54,96 @@ export class ApiGatewayV2Authorizer extends Component {
const self = this;

const api = output(args.api);
const jwt = output(args.jwt);
const lamb = args.lambda && output(args.lambda);
const jwt = args.jwt && output(args.jwt);

validateSingleAuthorizer();
const fn = createFunction();
const authorizer = createAuthorizer();
const permission = createPermission();

this.authorizer = authorizer;

function validateSingleAuthorizer() {
const authorizers = [lamb, jwt].filter((e) => e);

if (authorizers.length === 0)
throw new VisibleError(
`Please provide one of "lambda" or "jwt" for the ${args.name} authorizer.`,
);

if (authorizers.length > 1)
throw new VisibleError(
`Please provide only one of "lambda" or "jwt" for the ${args.name} authorizer.`,
);
}

function createFunction() {
if (!lamb) return;

return Function.fromDefinition(`${name}Function`, lamb.function, {
description: interpolate`${api.name} authorizer`,
});
}

function createAuthorizer() {
return new apigatewayv2.Authorizer(
...transform(
args.transform?.authorizer,
`${name}Authorizer`,
{
apiId: api.id,
authorizerType: "JWT",
identitySources: [
jwt.apply(
(jwt) => jwt.identitySource ?? "$request.header.Authorization",
),
],
jwtConfiguration: jwt.apply((jwt) => ({
audiences: jwt.audiences,
issuer: jwt.issuer,
})),
...(lamb
? {
authorizerType: "REQUEST",
identitySources: lamb.apply(
(lamb) =>
lamb.identitySources ?? ["$request.header.Authorization"],
),
authorizerUri: fn!.nodes.function.invokeArn,
authorizerResultTtlInSeconds: lamb.apply((lamb) =>
toSeconds(lamb.ttl ?? "0 seconds"),
),
enableSimpleResponses: lamb.apply(
(lamb) => (lamb.response ?? "simple") === "simple",
),
authorizerPayloadFormatVersion: lamb.apply(
(lamb) => lamb.payload ?? "2.0",
),
}
: {
authorizerType: "JWT",
identitySources: [
jwt!.apply(
(jwt) =>
jwt.identitySource ?? "$request.header.Authorization",
),
],
jwtConfiguration: jwt!.apply((jwt) => ({
audiences: jwt.audiences,
issuer: jwt.issuer,
})),
}),
},
{ parent: self },
),
);
}

function createPermission() {
if (!fn) return;

return new lambda.Permission(
`${name}Permission`,
{
action: "lambda:InvokeFunction",
function: fn.arn,
principal: "apigateway.amazonaws.com",
sourceArn: interpolate`${api.executionArn}/authorizers/${authorizer.id}`,
},
{ parent: self },
);
}
}

/**
Expand Down
5 changes: 5 additions & 0 deletions platform/src/components/aws/apigatewayv2-base-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export function createApiRoute(
const authArgs = output(args.auth).apply((auth) => {
if (!auth) return { authorizationType: "NONE" };
if (auth.iam) return { authorizationType: "AWS_IAM" };
if (auth.lambda)
return {
authorizationType: "CUSTOM",
authorizerId: auth.lambda,
};
if (auth.jwt)
return {
authorizationType: "JWT",
Expand Down
Loading

0 comments on commit 6d6a782

Please sign in to comment.