Skip to content

Commit

Permalink
feat: use powertools for additional logging
Browse files Browse the repository at this point in the history
  • Loading branch information
marnixdessing committed Feb 21, 2023
1 parent 4fef2d2 commit 08d9c48
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 12 deletions.
4 changes: 4 additions & 0 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .projenrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const project = new GemeenteNijmegenCdkApp({
'@types/cookie',
'cookie',
'@types/aws-lambda',
'@aws-lambda-powertools/logger',
],
devDeps: [
'copyfiles',
Expand Down
1 change: 1 addition & 0 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/app/auth/auth.lambda.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Logger } from '@aws-lambda-powertools/logger';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { Response } from '@gemeentenijmegen/apigateway-http';
import { handleRequest } from './handleRequest';

const logger = new Logger({ serviceName: 'YiviAuthLambda' });
const dynamoDBClient = new DynamoDBClient({});

function parseEvent(event: any) {
Expand All @@ -15,7 +17,7 @@ function parseEvent(event: any) {
exports.handler = async (event: any) => {
try {
const params = parseEvent(event);
return await handleRequest(params.cookies, params.code, params.state, dynamoDBClient);
return await handleRequest(params.cookies, params.code, params.state, dynamoDBClient, logger);
} catch (err) {
console.error(err);
return Response.error();
Expand Down
16 changes: 14 additions & 2 deletions src/app/auth/handleRequest.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
import { Logger } from '@aws-lambda-powertools/logger';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { Response } from '@gemeentenijmegen/apigateway-http';
import { Session } from '@gemeentenijmegen/session';
import { OpenIDConnect } from '../code/OpenIDConnect';

export async function handleRequest(cookies: string, queryStringParamCode: string, queryStringParamState: string, dynamoDBClient: DynamoDBClient) {
export async function handleRequest(
cookies: string,
queryStringParamCode: string,
queryStringParamState: string,
dynamoDBClient: DynamoDBClient,
logger: Logger,
) {
let session = new Session(cookies, dynamoDBClient);
await session.init();
if (session.sessionId === false) {
logger.info('No session found');
return Response.redirect('/login');
}
const state = session.getValue('state');
const OIDC = new OpenIDConnect();
try {
const claims = await OIDC.authorize(queryStringParamCode, state, queryStringParamState);
logger.debug('OIDC Claims', claims); // Log in debug to see the claims (set by LOG_LEVEL, see powertools)
if (claims) {
await session.createSession({
loggedin: { BOOL: true },
bsn: { S: claims.sub },
});
} else {
logger.info('Authentication failed');
return Response.redirect('/login');
}
} catch (error: any) {
console.error(error.message);
logger.info('Authentication failed');
logger.error(error.message);
return Response.redirect('/login');
}
logger.info('Authentication successful');
return Response.redirect('/', 302, session.getCookie());
}
13 changes: 8 additions & 5 deletions test/app/auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Logger } from '@aws-lambda-powertools/logger';
import { DynamoDBClient, GetItemCommand, GetItemCommandOutput } from '@aws-sdk/client-dynamodb';
import { SecretsManagerClient, GetSecretValueCommandOutput, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
import { mockClient } from 'aws-sdk-client-mock';
Expand Down Expand Up @@ -27,6 +28,7 @@ beforeAll(() => {

});

const logger = new Logger({ serviceName: 'YiviAuthLambda'});
const ddbMock = mockClient(DynamoDBClient);
const secretsMock = mockClient(SecretsManagerClient);

Expand Down Expand Up @@ -79,7 +81,7 @@ test('Successful auth redirects to home', async () => {
};
ddbMock.on(GetItemCommand).resolves(getItemOutput);

const result = await handleRequest(`session=${sessionId}`, 'state', '12345', dynamoDBClient);
const result = await handleRequest(`session=${sessionId}`, 'state', '12345', dynamoDBClient, logger);
expect(result.statusCode).toBe(302);
expect(result.headers?.Location).toBe('/');
});
Expand All @@ -101,15 +103,15 @@ test('Successful auth creates new session', async () => {
ddbMock.on(GetItemCommand).resolves(getItemOutput);


const result = await handleRequest(`session=${sessionId}`, 'state', '12345', dynamoDBClient);
const result = await handleRequest(`session=${sessionId}`, 'state', '12345', dynamoDBClient, logger);
expect(result.statusCode).toBe(302);
expect(result.headers?.Location).toBe('/');
expect(result.cookies).toContainEqual(expect.stringContaining('session='));
});

test('No session redirects to login', async () => {
const dynamoDBClient = new DynamoDBClient({ region: 'eu-west-1' });
const result = await handleRequest('', 'state', 'state', dynamoDBClient);
const result = await handleRequest('', 'state', 'state', dynamoDBClient, logger);
expect(result.statusCode).toBe(302);
expect(result.headers?.Location).toBe('/login');
});
Expand All @@ -128,9 +130,10 @@ test('Incorrect state errors', async () => {
},
},
};
const logger = new Logger({serviceName: 'test'});
ddbMock.on(GetItemCommand).resolves(getItemOutput);
const logSpy = jest.spyOn(console, 'error');
const result = await handleRequest(`session=${sessionId}`, '12345', 'returnedstate', dynamoDBClient);
const logSpy = jest.spyOn(logger, 'error');
const result = await handleRequest(`session=${sessionId}`, '12345', 'returnedstate', dynamoDBClient, logger);
expect(result.statusCode).toBe(302);
expect(result.headers?.Location).toBe('/login');
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('state does not match session state'));
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.dev.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tsconfig.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 08d9c48

Please sign in to comment.