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

fix!: Bugfix/supported events missing key #62

Merged
merged 3 commits into from
Jun 27, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions src/control-plane/auth/cognito-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ServicePrincipal,
Effect,
} from 'aws-cdk-lib/aws-iam';
import { Runtime, IFunction, LayerVersion, ILayerVersion } from 'aws-cdk-lib/aws-lambda';
import { Runtime, IFunction, LayerVersion } from 'aws-cdk-lib/aws-lambda';
import { NagSuppressions } from 'cdk-nag';
import { Construct } from 'constructs';
import { CreateAdminUserProps, IAuth } from './auth-interface';
Expand Down Expand Up @@ -209,16 +209,17 @@ export class CognitoAuth extends Construct implements IAuth {
private readonly userPool: cognito.UserPool;

/**
* The Lambda Layer containing the Powertools library.
* The Lambda function for creating a new Admin User. This is used as part of a
* custom resource in CloudFormation to create an admin user.
*/
private readonly lambdaPowertoolsLayer: ILayerVersion;
private readonly createAdminUserFunction: IFunction;

constructor(scope: Construct, id: string, props?: CognitoAuthProps) {
super(scope, id);
addTemplateTag(this, 'CognitoAuth');

// https://docs.powertools.aws.dev/lambda/python/2.31.0/#lambda-layer
this.lambdaPowertoolsLayer = LayerVersion.fromLayerVersionArn(
const lambdaPowertoolsLayer = LayerVersion.fromLayerVersionArn(
this,
'LambdaPowerTools',
`arn:aws:lambda:${Stack.of(this).region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59`
Expand Down Expand Up @@ -460,7 +461,7 @@ export class CognitoAuth extends Construct implements IAuth {
handler: 'lambda_handler',
timeout: Duration.seconds(60),
role: userManagementExecRole,
layers: [this.lambdaPowertoolsLayer],
layers: [lambdaPowertoolsLayer],
environment: {
USER_POOL_ID: this.userPool.userPoolId,
},
Expand Down Expand Up @@ -495,25 +496,23 @@ export class CognitoAuth extends Construct implements IAuth {
},
]
);
}

createAdminUser(scope: Construct, id: string, props: CreateAdminUserProps) {
const createAdminUserFunction = new PythonFunction(scope, `createAdminUserFunction-${id}`, {
this.createAdminUserFunction = new PythonFunction(scope, 'createAdminUserFunction', {
entry: path.join(__dirname, '../../../resources/functions/auth-custom-resource'),
runtime: Runtime.PYTHON_3_12,
index: 'index.py',
handler: 'handler',
timeout: Duration.seconds(60),
layers: [this.lambdaPowertoolsLayer],
layers: [lambdaPowertoolsLayer],
});
this.userPool.grant(
createAdminUserFunction,
this.createAdminUserFunction,
'cognito-idp:AdminCreateUser',
'cognito-idp:AdminDeleteUser'
);

NagSuppressions.addResourceSuppressions(
createAdminUserFunction.role!,
this.createAdminUserFunction.role!,
[
{
id: 'AwsSolutions-IAM4',
Expand All @@ -525,9 +524,11 @@ export class CognitoAuth extends Construct implements IAuth {
],
true // applyToChildren = true, so that it applies to policies created for the role.
);
}

createAdminUser(scope: Construct, id: string, props: CreateAdminUserProps) {
new CustomResource(scope, `createAdminUserCustomResource-${id}`, {
serviceToken: createAdminUserFunction.functionArn,
serviceToken: this.createAdminUserFunction.functionArn,
properties: {
UserPoolId: this.userPool.userPoolId,
Name: props.name,
Expand Down
6 changes: 1 addition & 5 deletions src/control-plane/control-plane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,7 @@ export class ControlPlane extends Construct {

cdk.Aspects.of(this).add(new DestroyPolicySetter());

const auth =
props.auth ||
new CognitoAuth(this, 'CognitoAuth', {
setAPIGWScopes: false,
});
const auth = props.auth || new CognitoAuth(this, 'CognitoAuth');

auth.createAdminUser(this, 'adminUser', {
name: systemAdminName,
Expand Down
7 changes: 6 additions & 1 deletion src/control-plane/integ.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as cdk from 'aws-cdk-lib';
import { CfnRule, EventBus, Rule } from 'aws-cdk-lib/aws-events';
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
import { AwsSolutionsChecks } from 'cdk-nag';
import { ControlPlane } from '.';
import { CognitoAuth, ControlPlane } from '.';
import { DestroyPolicySetter } from '../cdk-aspect/destroy-policy-setter';

export interface IntegStackProps extends cdk.StackProps {
Expand All @@ -16,7 +16,12 @@ export class IntegStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props: IntegStackProps) {
super(scope, id, props);

const cognitoAuth = new CognitoAuth(this, 'CognitoAuth', {
setAPIGWScopes: false, // only for testing purposes!
});

const controlPlane = new ControlPlane(this, 'ControlPlane', {
auth: cognitoAuth,
systemAdminEmail: props.systemAdminEmail,
});

Expand Down
2 changes: 2 additions & 0 deletions src/utils/event-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ export class EventManager extends Construct implements IEventManager {
deactivateRequest: this.controlPlaneEventSource,
deactivateSuccess: this.applicationPlaneEventSource,
deactivateFailure: this.applicationPlaneEventSource,
tenantUserCreated: this.controlPlaneEventSource,
tenantUserDeleted: this.controlPlaneEventSource,
};

for (const key in this.supportedEvents) {
Expand Down
17 changes: 17 additions & 0 deletions test/event-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,21 @@ describe('EventManager', () => {
testForRulesInOtherStack(controlPlaneStack);
testForRulesInOtherStack(eventManagerStack);
});

describe('supportedEvents in event-manager', () => {
const app = new cdk.App();
const eventManagerStack = new cdk.Stack(app, 'EventManagerStack');
const eventManager = new EventManager(eventManagerStack, 'EventManager');

// This ensures that when we try and use supportedEvents to create a rule,
// and key-in using a DetailType, a value exists for the source,
// which is used in the getOrCreateRule(...) function to create
// a new event-manager rule.
// (ex. "source: [this.supportedEvents[eventType]]")
it('should have values for all DetailType enum entries', () => {
Object.values(DetailType).forEach((detailTypeValues) => {
expect(eventManager.supportedEvents[detailTypeValues]).toBeDefined();
});
});
});
});
Loading