Skip to content

Commit

Permalink
Added Auth Lambda
Browse files Browse the repository at this point in the history
  • Loading branch information
grishabh1992 committed Jan 31, 2022
1 parent a9f3ee2 commit 5a6b63e
Show file tree
Hide file tree
Showing 16 changed files with 1,270 additions and 704 deletions.
12 changes: 5 additions & 7 deletions bin/chat_api_app_sync.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { ChatApiAppSyncStack } from '../lib/chat_api_app_sync-stack';
import "source-map-support/register";
import * as cdk from "@aws-cdk/core";
import { ChatApiAppSyncStack } from "../lib/chat_api_app_sync-stack";

const app = new cdk.App();
new ChatApiAppSyncStack(app, 'ChatApiAppSyncStack', {
new ChatApiAppSyncStack(app, "ChatApiAppSyncStack", {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */

/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },

/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
env: { region: "ap-south-1" },
});
20 changes: 20 additions & 0 deletions lib/auth-lambda.construct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as cdk from "@aws-cdk/core";
import * as iam from "@aws-cdk/aws-iam";
import * as nodeLambda from "@aws-cdk/aws-lambda-nodejs";

export class AuthLambdaConstruct extends cdk.Stack {
readonly lambda: nodeLambda.NodejsFunction;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

this.lambda = new nodeLambda.NodejsFunction(this, "AppSyncAuthHandler", {
functionName: `custom-authoriser`,
description: `This Lambda is excuted fauthenticate the user.`,
retryAttempts: 0,
entry: "src/lambdas/auth.ts",
handler: "handler",
});

this.lambda.grantInvoke(new iam.ServicePrincipal("appsync.amazonaws.com"));
}
}
132 changes: 41 additions & 91 deletions lib/chat_api_app_sync-stack.ts
Original file line number Diff line number Diff line change
@@ -1,115 +1,65 @@
import * as cdk from "@aws-cdk/core";
import * as cdkCore from "@aws-cdk/core";
import * as appsync from "@aws-cdk/aws-appsync";
import * as dynamoDb from "@aws-cdk/aws-dynamoDb";
import * as lambda from "@aws-cdk/aws-lambda";
// import { Code, Function, Runtime } from '@aws-cdk/aws-lambda';
// import * as sqs from '@aws-cdk/aws-sqs';
import { GraphQlAPIConstruct } from "./graph-api.construct";
import { LambdaConstruct } from "./lambda.contruct";
import { DynamoDBConstruct } from "./dynamo-db.construct";

export class ChatApiAppSyncStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const MessagesTable = new dynamoDb.Table(this, "MessagesTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
sortKey: { name: "conversationId", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdkCore.RemovalPolicy.DESTROY,
tableName: "messages-table",
});
const dynamoDBConstruct = new DynamoDBConstruct(
this,
`${id}-dynamo-db`,
props
);

const ConversationsTable = new dynamoDb.Table(this, "ConversationsTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdkCore.RemovalPolicy.DESTROY,
tableName: "conversations-table",
});
const lambdaConstruct = new LambdaConstruct(this, `${id}-lambda`, props);

const UsersTable = new dynamoDb.Table(this, "UsersTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdkCore.RemovalPolicy.DESTROY,
tableName: "users-table",
});
const graphAPIContruct = new GraphQlAPIConstruct(
this,
`${id}-graph-api`,
props
);

const api = new appsync.GraphqlApi(this, "ChatsApi", {
name: "chat-api",
logConfig: {
fieldLogLevel: appsync.FieldLogLevel.ERROR,
},
schema: appsync.Schema.fromAsset("src/graphql/schema.graphql"),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.API_KEY,
apiKeyConfig: {
expires: cdk.Expiration.after(cdk.Duration.days(365)),
},
},
},
// xrayEnabled: true,
});
// enable the Lambda function to access the DynamoDB table (using IAM)
dynamoDBConstruct.messagesTable.grantFullAccess(lambdaConstruct.lambda);
dynamoDBConstruct.notificationTable.grantFullAccess(lambdaConstruct.lambda);
dynamoDBConstruct.conversationsTable.grantFullAccess(
lambdaConstruct.lambda
);
dynamoDBConstruct.usersTable.grantFullAccess(lambdaConstruct.lambda);

// Create an environment variable that we will use in the function code
lambdaConstruct.lambda.addEnvironment(
"MESSAGES_TABLE",
dynamoDBConstruct.messagesTable.tableName
);
lambdaConstruct.lambda.addEnvironment(
"CONVERSATIONS_TABLE",
dynamoDBConstruct.conversationsTable.tableName
);
lambdaConstruct.lambda.addEnvironment(
"USERS_TABLE",
dynamoDBConstruct.usersTable.tableName
);
lambdaConstruct.lambda.addEnvironment(
"NOTIFICATIONS_TABLE",
dynamoDBConstruct.notificationTable.tableName
);

// Prints out the AppSync GraphQL endpoint to the terminal
new cdk.CfnOutput(this, "GraphQLAPIURL", {
value: api.graphqlUrl,
value: graphAPIContruct.api.graphqlUrl,
});

// Prints out the AppSync GraphQL API key to the terminal
new cdk.CfnOutput(this, "GraphQLAPIKey", {
value: api.apiKey || "",
value: graphAPIContruct.api.apiKey || "",
});

// Prints out the stack region to the terminal
new cdk.CfnOutput(this, "Stack Region", {
value: this.region,
});

// const chatsLambda = new lambda.Function(this, "AppSyncChatRouteHandler", {
// runtime: lambda.Runtime.NODEJS_12_X,
// handler: "routes.handler",
// code: lambda.Code.fromAsset("src"),
// memorySize: 1024,
// });

// // Set the new Lambda function as a data source for the AppSync API
// const lambdaDs = api.addLambdaDataSource("lambdaDatasource", chatsLambda);

// lambdaDs.createResolver({
// typeName: "Query",
// fieldName: "getConversations",
// });

// lambdaDs.createResolver({
// typeName: "Query",
// fieldName: "getConversation",
// });

// lambdaDs.createResolver({
// typeName: "Mutation",
// fieldName: "addConversation",
// });

// lambdaDs.createResolver({
// typeName: "Mutation",
// fieldName: "addMessage",
// });

// lambdaDs.createResolver({
// typeName: "Mutation",
// fieldName: "addUser",
// });

// enable the Lambda function to access the DynamoDB table (using IAM)
// MessagesTable.grantFullAccess(chatsLambda);
// ConversationsTable.grantFullAccess(chatsLambda);
// UsersTable.grantFullAccess(chatsLambda);

// // Create an environment variable that we will use in the function code
// chatsLambda.addEnvironment("MESSAGES_TABLE", MessagesTable.tableName);
// chatsLambda.addEnvironment(
// "CONVERSATIONS_TABLE",
// ConversationsTable.tableName
// );
// chatsLambda.addEnvironment("USERS_TABLE", UsersTable.tableName);
}
}
43 changes: 43 additions & 0 deletions lib/dynamo-db.construct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as cdk from "@aws-cdk/core";
import * as dynamoDb from "@aws-cdk/aws-dynamoDb";

export class DynamoDBConstruct extends cdk.Stack {
readonly messagesTable: dynamoDb.Table;
readonly conversationsTable: dynamoDb.Table;
readonly usersTable: dynamoDb.Table;
readonly notificationTable: dynamoDb.Table;

constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

this.messagesTable = new dynamoDb.Table(this, "MessagesTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "conversationId", type: dynamoDb.AttributeType.STRING },
sortKey: { name: "createdAt", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.DESTROY,
tableName: "messages-table",
});

this.conversationsTable = new dynamoDb.Table(this, "ConversationsTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.DESTROY,
tableName: "conversations-table",
});

this.usersTable = new dynamoDb.Table(this, "UsersTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.DESTROY,
tableName: "users-table",
});

this.notificationTable = new dynamoDb.Table(this, "NotificationsTable", {
billingMode: dynamoDb.BillingMode.PAY_PER_REQUEST,
partitionKey: { name: "id", type: dynamoDb.AttributeType.STRING },
sortKey: { name: "createdAt", type: dynamoDb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.DESTROY,
tableName: "notifications-table",
});
}
}
36 changes: 36 additions & 0 deletions lib/graph-api.construct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as cdk from "@aws-cdk/core";
import * as appsync from "@aws-cdk/aws-appsync";
import * as nodeLambda from "@aws-cdk/aws-lambda-nodejs";
import * as iam from "@aws-cdk/aws-iam";
import { AuthLambdaConstruct } from "./auth-lambda.construct";

export class GraphQlAPIConstruct extends cdk.Stack {
readonly api: appsync.GraphqlApi;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const athLambdaConstruct = new AuthLambdaConstruct(
this,
`${id}-auth-lambda`,
props
);

this.api = new appsync.GraphqlApi(this, "ChatsApi", {
name: "chat-api",
schema: appsync.Schema.fromAsset("src/graphql/schema.graphql"),
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.LAMBDA,
lambdaAuthorizerConfig: {
handler: athLambdaConstruct.lambda,
},
// // API Key Authentication
// authorizationType: appsync.AuthorizationType.API_KEY,
// apiKeyConfig: {
// expires: cdk.Expiration.after(cdk.Duration.days(365)),
// },
},
},
});
}
}
60 changes: 60 additions & 0 deletions lib/graphql/graphql-resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as appsync from "@aws-cdk/aws-appsync";
import * as nodeLambda from "@aws-cdk/aws-lambda-nodejs";

export const bindResolvers = (
api: appsync.GraphqlApi,
lambda: nodeLambda.NodejsFunction
) => {
// Set the new Lambda function as a data source for the AppSync API
const lambdaDs = api.addLambdaDataSource("lambdaDatasource", lambda);

lambdaDs.createResolver({
typeName: "Query",
fieldName: "conversations",
});

lambdaDs.createResolver({
typeName: "Query",
fieldName: "users",
});

lambdaDs.createResolver({
typeName: "Query",
fieldName: "conversation",
});

lambdaDs.createResolver({
typeName: "Query",
fieldName: "notifications",
});

lambdaDs.createResolver({
typeName: "Mutation",
fieldName: "createConversation",
});

lambdaDs.createResolver({
typeName: "Mutation",
fieldName: "addMessage",
});

lambdaDs.createResolver({
typeName: "Mutation",
fieldName: "createUser",
});

lambdaDs.createResolver({
typeName: "Mutation",
fieldName: "addNotification",
});

lambdaDs.createResolver({
typeName: "Subscription",
fieldName: "onCreateUser",
});

lambdaDs.createResolver({
typeName: "Subscription",
fieldName: "onCreateNotification",
});
};
21 changes: 21 additions & 0 deletions lib/lambda.contruct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as cdk from "@aws-cdk/core";
import * as nodeLambda from "@aws-cdk/aws-lambda-nodejs";

export class LambdaConstruct extends cdk.Stack {
readonly lambda: nodeLambda.NodejsFunction;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

this.lambda = new nodeLambda.NodejsFunction(
this,
"AppSyncChatRouteHandler",
{
functionName: `chat-routing`,
description: `This Lambda is excuted from graphql to trigger lambda.`,
retryAttempts: 0,
entry: "src/routes.ts",
handler: "handler",
}
);
}
}
Loading

0 comments on commit 5a6b63e

Please sign in to comment.