Skip to content

Commit 2a4e13c

Browse files
committed
Implement permissions from manual JSON files
1 parent 6a853bf commit 2a4e13c

File tree

10 files changed

+80
-274
lines changed

10 files changed

+80
-274
lines changed

cdk/app.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import aws_cdk as cdk
55

6+
from quiz_app.frontend_stack import FrontendStack
67
from quiz_app.quiz_app_stack import QuizAppStack
78

89

@@ -25,4 +26,6 @@
2526
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
2627
)
2728

29+
FrontendStack(app, "FrontendStack")
30+
2831
app.synth()

cdk/quiz_app/frontend_stack.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import os
2+
3+
import aws_cdk
4+
from aws_cdk import (
5+
Stack,
6+
aws_s3 as s3,
7+
aws_cloudfront as cf,
8+
aws_cloudfront_origins as origins,
9+
aws_s3_deployment as s3deploy,
10+
CfnOutput,
11+
)
12+
from constructs import Construct
13+
14+
15+
class FrontendStack(Stack):
16+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
17+
super().__init__(scope, construct_id, **kwargs)
18+
19+
webapp_bucket = s3.Bucket(
20+
self,
21+
"WebAppBucket",
22+
auto_delete_objects=True,
23+
removal_policy=aws_cdk.RemovalPolicy.DESTROY,
24+
)
25+
origin_access_identity = cf.OriginAccessIdentity(self, "OriginAccessIdentity")
26+
webapp_bucket.grant_read(origin_access_identity)
27+
28+
# deploy process
29+
distribution = cf.Distribution(
30+
self,
31+
"FrontendDistribution",
32+
default_root_object="index.html",
33+
default_behavior=cf.BehaviorOptions(
34+
origin=origins.S3Origin(
35+
webapp_bucket,
36+
origin_access_identity=origin_access_identity,
37+
),
38+
viewer_protocol_policy=cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
39+
),
40+
)
41+
42+
s3deploy.BucketDeployment(
43+
self,
44+
"DeployApp",
45+
sources=[
46+
s3deploy.Source.asset(
47+
os.path.join(
48+
os.path.dirname(__file__), "..", "..", "frontend", "build"
49+
)
50+
),
51+
],
52+
destination_bucket=webapp_bucket,
53+
distribution=distribution,
54+
distribution_paths=["/*"],
55+
)
56+
57+
CfnOutput(self, "DistributionDomainName", value=distribution.domain_name)
58+

cdk/quiz_app/quiz_app_stack.py

Lines changed: 19 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,25 @@
11
import json
22
from pathlib import Path
3-
from tty import CFLAG
43

54
import aws_cdk
65
from aws_cdk import (
7-
# Duration,
86
Stack,
9-
aws_s3 as s3,
107
aws_apigateway as apigateway,
118
aws_dynamodb as dynamodb,
12-
aws_cloudfront as cf,
139
aws_iam as iam,
1410
aws_lambda as _lambda,
15-
aws_lambda_nodejs as _jslambda,
1611
aws_sns as sns,
1712
aws_stepfunctions as sfn,
1813
aws_pipes as pipes,
1914
aws_sqs as sqs,
2015
custom_resources as cr,
21-
CfnOutput as Output,
2216
)
2317
from constructs import Construct
2418

2519

2620
class QuizAppStack(Stack):
21+
backend_api_url: str
22+
2723
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
2824
super().__init__(scope, construct_id, **kwargs)
2925

@@ -81,91 +77,52 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
8177
functions_and_roles = [
8278
(
8379
"CreateQuizFunction",
84-
"configurations/create_quiz_policy.json",
85-
"CreateQuizRole",
8680
"lambdas/get_quiz",
8781
),
8882
(
8983
"GetQuizFunction",
90-
"configurations/get_quiz_policy.json",
91-
"GetQuizRole",
9284
"lambdas/get_quiz",
9385
),
9486
(
9587
"SubmitQuizFunction",
96-
"configurations/submit_quiz_policy.json",
97-
"SubmitQuizRole",
9888
"lambdas/submit_quiz",
9989
),
10090
(
10191
"ScoringFunction",
102-
"configurations/scoring_policy.json",
103-
"ScoringRole",
10492
"lambdas/scoring",
10593
),
10694
(
10795
"GetSubmissionFunction",
108-
"configurations/get_submission_policy.json",
109-
"GetSubmissionRole",
11096
"lambdas/get_submission",
11197
),
11298
(
11399
"GetLeaderboardFunction",
114-
"configurations/get_leaderboard_policy.json",
115-
"GetLeaderboardRole",
116100
"lambdas/get_leaderboard",
117101
),
118102
(
119103
"ListPublicQuizzesFunction",
120-
"configurations/list_quizzes_policy.json",
121-
"ListQuizzesRole",
122104
"lambdas/list_quizzes",
123105
),
124106
(
125107
"RetryQuizzesWritesFunction",
126-
"configurations/retry_quizzes_writes_policy.json",
127-
"RetryQuizzesWritesRole",
128108
"lambdas/retry_quizzes_writes",
129109
),
130110
]
131111
functions = {}
132112

133113
for function_info in functions_and_roles:
134-
function_name, policy_file_path, role_name, handler_path = function_info
135-
policy_json = self.read_policy_file(f"../{policy_file_path}")
136-
policy_document = iam.PolicyDocument.from_json(policy_json)
137-
138-
policy = iam.ManagedPolicy(
139-
self,
140-
f"{function_name}FunctionPolicy",
141-
managed_policy_name=f"{function_name}Policy",
142-
document=policy_document,
143-
)
144-
145-
role = iam.Role(
146-
self,
147-
f"{function_name}LambdaExecutionRole",
148-
role_name=role_name,
149-
assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
150-
description=f"Role for Lambda function {function_name}",
151-
)
152-
153-
# Attach the policy to the role
154-
role.add_managed_policy(policy)
155-
114+
function_name, handler_path = function_info
156115
current_function = _lambda.Function(
157116
self,
158117
f"{function_name}LambdaFunction",
159118
function_name=function_name,
160119
runtime=_lambda.Runtime.PYTHON_3_11,
161120
handler="handler.lambda_handler",
162121
code=_lambda.Code.from_asset(f"../{handler_path}"),
163-
role=role,
164122
timeout=aws_cdk.Duration.seconds(30),
165123
)
166124
functions[function_name] = current_function
167125

168-
submission_queue.grant_consume_messages(functions["ScoringFunction"])
169126
_lambda.EventSourceMapping(
170127
self,
171128
"ScoringFunctionSubscription",
@@ -190,6 +147,8 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
190147
)
191148
resource.add_method(http_method, integration=integration)
192149

150+
self.backend_api_url = rest_api.url
151+
193152
# verify email identity for SES
194153
195154
sanitised_email = email.replace(".", "-").replace("@", "-")
@@ -297,33 +256,18 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
297256
role=state_machine_role,
298257
)
299258

300-
webapp_bucket = s3.Bucket(
301-
self,
302-
"WebAppBucket",
303-
auto_delete_objects=True,
304-
removal_policy=aws_cdk.RemovalPolicy.DESTROY,
305-
)
306-
origin_access_identity = cf.OriginAccessIdentity(self, "OriginAccessIdentity")
307-
webapp_bucket.grant_read(origin_access_identity)
308-
custom_resource_lambda = _lambda.Function(
309-
self,
310-
"WebsiteDeployFunction",
311-
runtime=_lambda.Runtime.NODEJS_LATEST,
312-
handler="index.handler",
313-
memory_size=1024,
314-
ephemeral_storage_size=aws_cdk.Size.gibibytes(8),
315-
code=_lambda.Code.from_asset("./website_deploy"),
316-
timeout=aws_cdk.Duration.seconds(300),
317-
# TODO
318-
environment={},
319-
)
320-
webapp_bucket.grant_write(custom_resource_lambda)
321259

322-
@staticmethod
323-
def read_policy_file(file_path: str) -> dict:
324-
"""Reads a JSON policy file and returns it as a dictionary."""
325-
file_path = Path(file_path)
326-
if not file_path.exists():
327-
raise FileNotFoundError(f"Policy file not found: {file_path}")
328-
with open(file_path, "r") as file:
329-
return json.load(file)
260+
# set up lambda permissions
261+
quizzes_table.grant_write_data(functions["CreateQuizFunction"])
262+
# TODO: createquizfunction should be able to write to QuizzesWriteFailures
263+
quizzes_table.grant_read_data(functions["GetQuizFunction"])
264+
quizzes_table.grant_read_data(functions["SubmitQuizFunction"])
265+
quizzes_table.grant_read_write_data(functions["ScoringFunction"])
266+
self.state_machine.grant_start_execution(functions["ScoringFunction"])
267+
submission_queue.grant_consume_messages(functions["ScoringFunction"])
268+
user_submissions_table.grant_read_write_data(functions["ScoringFunction"])
269+
user_submissions_table.grant_read_data(functions["GetSubmissionFunction"])
270+
user_submissions_table.grant_read_data(functions["GetLeaderboardFunction"])
271+
quizzes_table.grant_read_data(functions["ListPublicQuizzesFunction"])
272+
quizzes_table.grant_read_write_data(functions["RetryQuizzesWritesFunction"])
273+
# TODO: retryquizzeswritesfunction should have access to read and write to quizzeswritefailuresqueue

configurations/get_leaderboard_policy.json

Lines changed: 0 additions & 25 deletions
This file was deleted.

configurations/get_quiz_policy.json

Lines changed: 0 additions & 22 deletions
This file was deleted.

configurations/get_submission_policy.json

Lines changed: 0 additions & 23 deletions
This file was deleted.

configurations/list_quizzes_policy.json

Lines changed: 0 additions & 22 deletions
This file was deleted.

configurations/retry_quizzes_writes_policy.json

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)