Skip to content

Commit 4f1b487

Browse files
authored
Merge pull request #12 from emmaLP/auth
Implementing simple authorisation on the api gateway
2 parents fd36554 + 58dd1cc commit 4f1b487

File tree

8 files changed

+151
-3
lines changed

8 files changed

+151
-3
lines changed

deploy/api_gateway.tf

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ resource "aws_apigatewayv2_stage" "default" {
1111

1212

1313
resource "aws_apigatewayv2_route" "pack_calc" {
14-
api_id = aws_apigatewayv2_api.pack_calc.id
15-
route_key = "POST /calculate-packs"
16-
target = "integrations/${aws_apigatewayv2_integration.pack_calc.id}"
14+
api_id = aws_apigatewayv2_api.pack_calc.id
15+
authorization_type = "CUSTOM"
16+
authorizer_id = aws_apigatewayv2_authorizer.authoriser.id
17+
route_key = "POST /calculate-packs"
18+
target = "integrations/${aws_apigatewayv2_integration.pack_calc.id}"
1719
}
1820

1921
resource "aws_apigatewayv2_integration" "pack_calc" {
@@ -23,4 +25,16 @@ resource "aws_apigatewayv2_integration" "pack_calc" {
2325
integration_uri = aws_lambda_function.pack_calc.invoke_arn
2426
integration_method = "POST"
2527
payload_format_version = "2.0"
28+
}
29+
30+
resource "aws_apigatewayv2_authorizer" "authoriser" {
31+
api_id = aws_apigatewayv2_api.pack_calc.id
32+
authorizer_type = "REQUEST"
33+
authorizer_uri = aws_lambda_function.token_authoriser.invoke_arn
34+
35+
identity_sources = ["$request.header.Authorization"]
36+
authorizer_payload_format_version = "2.0"
37+
name = "gymshark-token-authoriser"
38+
enable_simple_responses = true
39+
authorizer_result_ttl_in_seconds = 0
2640
}

deploy/data.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
data "aws_iam_policy" "lambda_execution" {
22
arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
3+
}
4+
data "aws_iam_policy" "ssm_readonly" {
5+
arn = "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"
36
}

deploy/files/token_authoriser.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const AWS = require('aws-sdk');
2+
3+
AWS.config.region = process.env.AWS_DEFAULT_REGION || 'eu-west-2';
4+
5+
function getSecret(secretKey) {
6+
return new Promise((resolve, reject) => {
7+
const ssm = new AWS.SSM();
8+
const params = {
9+
Name: secretKey,
10+
WithDecryption: true
11+
};
12+
console.log("calling sdk ssm");
13+
ssm.getParameter(params, function (err, data) {
14+
console.log("ssm - request made");
15+
if (err) {
16+
console.error(err);
17+
return reject(err);
18+
}
19+
if (!data.Parameter) {
20+
console.error("secret not found");
21+
return reject(new Error('Token not found'));
22+
}
23+
console.log("Found secret");
24+
return resolve(data.Parameter.Value);
25+
});
26+
});
27+
}
28+
29+
exports.handler = async (event) => {
30+
console.log(event)
31+
let response = {
32+
"isAuthorized": false,
33+
"context": {
34+
"stringKey": "value",
35+
"numberKey": 1,
36+
"booleanKey": true,
37+
"arrayKey": ["value1", "value2"],
38+
"mapKey": {"value1": "value2"}
39+
}
40+
};
41+
let authHeader = event.headers['authorization']
42+
console.log("Auth Header", authHeader)
43+
await getSecret(process.env.SECRET_KEY)
44+
.then(secret => {
45+
if (!authHeader === secret) {
46+
response = {
47+
"isAuthorized": false,
48+
"context": {
49+
"booleanKey": true,
50+
}
51+
}
52+
} else {
53+
response = {
54+
"isAuthorized": true,
55+
"context": {
56+
"booleanKey": true,
57+
}
58+
}
59+
}
60+
})
61+
.catch(err => {
62+
// trap any errors and respond with '500 Server Error'
63+
console.error(err);
64+
response = {
65+
"isAuthorized": false
66+
}
67+
});
68+
69+
console.log("Response", response)
70+
return response;
71+
72+
};

deploy/lambda.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,43 @@ data "archive_file" "pack_calc" {
2020
output_path = "${path.module}/.terraform/archives/gymshark-pack-calc.zip"
2121
}
2222

23+
data "archive_file" "token_authorizer" {
24+
type = "zip"
25+
source_file = "${path.module}/files/token_authoriser.js"
26+
output_path = "${path.module}/.terraform/archives/token_authorizer.zip"
27+
}
28+
2329
resource "aws_lambda_permission" "apigateway" {
2430
action = "lambda:InvokeFunction"
2531
function_name = aws_lambda_function.pack_calc.function_name
2632
principal = "apigateway.amazonaws.com"
2733
source_arn = "${aws_apigatewayv2_api.pack_calc.execution_arn}/*/*/*"
34+
}
35+
36+
37+
resource "aws_lambda_function" "token_authoriser" {
38+
depends_on = [aws_cloudwatch_log_group.token_authoriser]
39+
function_name = "gymshark-pack-calc-authorizer"
40+
handler = "token_authoriser.handler"
41+
role = aws_iam_role.lambda.arn
42+
runtime = "nodejs12.x"
43+
environment {
44+
variables = {
45+
SECRET_KEY = aws_ssm_parameter.api_token.name
46+
}
47+
}
48+
filename = data.archive_file.token_authorizer.output_path
49+
source_code_hash = data.archive_file.token_authorizer.output_base64sha256
50+
51+
}
52+
resource "aws_cloudwatch_log_group" "token_authoriser" {
53+
name = "/aws/lambda/gymshark-pack-calc-authorizer"
54+
retention_in_days = 14
55+
}
56+
57+
resource "aws_lambda_permission" "apigateway_auth" {
58+
action = "lambda:InvokeFunction"
59+
function_name = aws_lambda_function.token_authoriser.function_name
60+
principal = "apigateway.amazonaws.com"
61+
source_arn = "${aws_apigatewayv2_api.pack_calc.execution_arn}/authorizers/${aws_apigatewayv2_authorizer.authoriser.id}"
2862
}

deploy/outputs.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "api_base_url" {
2+
value = aws_apigatewayv2_api.pack_calc.api_endpoint
3+
}

deploy/provider.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ terraform {
55
source = "hashicorp/aws"
66
version = "~> 3.0"
77
}
8+
random = {
9+
source = "hashicorp/random"
10+
version = "~> 3.0"
11+
}
812
archive = {
913
source = "hashicorp/archive"
1014
version = "~> 2"

deploy/roles.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ resource "aws_iam_role_policy_attachment" "lambda_execution" {
2121
role = aws_iam_role.lambda.name
2222
policy_arn = data.aws_iam_policy.lambda_execution.arn
2323
}
24+
resource "aws_iam_role_policy_attachment" "ssm_readonly" {
25+
role = aws_iam_role.lambda.name
26+
policy_arn = data.aws_iam_policy.ssm_readonly.arn
27+
}

deploy/secrets.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
resource "aws_ssm_parameter" "api_token" {
3+
name = "gmyshark-api-token"
4+
type = "SecureString"
5+
value = random_password.api_token.result
6+
}
7+
8+
resource "random_password" "api_token" {
9+
length = 16
10+
special = true
11+
upper = true
12+
lower = true
13+
override_special = "!@#$_-"
14+
}

0 commit comments

Comments
 (0)