Skip to content

Commit

Permalink
Frontend Global Imports, Backend Validation for custom auth params an…
Browse files Browse the repository at this point in the history
…d alb frontend changes as per custom auth
  • Loading branch information
TejasRGitHub authored and trajopadhye committed Dec 8, 2023
1 parent 393a282 commit 6f3aee3
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 112 deletions.
116 changes: 59 additions & 57 deletions deploy/stacks/albfront_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(
image_tag=None,
custom_domain=None,
ip_ranges=None,
custom_auth=None,
**kwargs,
):
super().__init__(scope, id, **kwargs)
Expand Down Expand Up @@ -220,65 +221,66 @@ def __init__(
)
self.allow_alb_access(frontend_alb, ip_ranges, vpc)

userguide_sg = ec2.SecurityGroup(
self,
'FargateTaskUserGuideSG',
security_group_name=f'{resource_prefix}-{envname}-userguide-service-sg',
vpc=vpc,
allow_all_outbound=True,
)
userguide_alb = ecs_patterns.ApplicationLoadBalancedFargateService(
self,
f'UserGuideService{envname}',
cluster=cluster,
cpu=1024,
memory_limit_mib=2048,
service_name=f'userguide-{envname}',
desired_count=1,
certificate=certificate if (custom_domain and custom_domain.get('certificate_arn')) else None,
domain_name=userguide_alternate_domain,
domain_zone=hosted_zone,
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
container_port=80,
environment={
'AWS_REGION': self.region,
'envname': envname,
'LOGLEVEL': 'DEBUG',
},
task_role=task_role,
image=ecs.ContainerImage.from_ecr_repository(
repository=ecr_repository, tag=userguide_image_tag
),
enable_logging=True,
log_driver=ecs.LogDriver.aws_logs(
stream_prefix='service',
log_group=self.create_log_group(
envname, resource_prefix, log_group_name='userguide'
if custom_auth is None:
userguide_sg = ec2.SecurityGroup(
self,
'FargateTaskUserGuideSG',
security_group_name=f'{resource_prefix}-{envname}-userguide-service-sg',
vpc=vpc,
allow_all_outbound=True,
)
userguide_alb = ecs_patterns.ApplicationLoadBalancedFargateService(
self,
f'UserGuideService{envname}',
cluster=cluster,
cpu=1024,
memory_limit_mib=2048,
service_name=f'userguide-{envname}',
desired_count=1,
certificate=certificate if (custom_domain and custom_domain.get('certificate_arn')) else None,
domain_name=userguide_alternate_domain,
domain_zone=hosted_zone,
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
container_port=80,
environment={
'AWS_REGION': self.region,
'envname': envname,
'LOGLEVEL': 'DEBUG',
},
task_role=task_role,
image=ecs.ContainerImage.from_ecr_repository(
repository=ecr_repository, tag=userguide_image_tag
),
enable_logging=True,
log_driver=ecs.LogDriver.aws_logs(
stream_prefix='service',
log_group=self.create_log_group(
envname, resource_prefix, log_group_name='userguide'
),
),
),
),
public_load_balancer=False,
assign_public_ip=False,
open_listener=False,
max_healthy_percent=100,
min_healthy_percent=0,
security_groups=[userguide_sg],
)
ulb: elb.CfnLoadBalancer = userguide_alb.load_balancer.node.default_child
ulb.access_logging_policy = elb.CfnLoadBalancer.AccessLoggingPolicyProperty(
enabled=True,
s3_bucket_name=logs_bucket.bucket_name,
s3_bucket_prefix='userguide',
)
userguide_alb.target_group.configure_health_check(
port='80',
path='/',
timeout=Duration.seconds(10),
healthy_threshold_count=2,
unhealthy_threshold_count=2,
interval=Duration.seconds(15),
)
self.allow_alb_access(userguide_alb, ip_ranges, vpc)
public_load_balancer=False,
assign_public_ip=False,
open_listener=False,
max_healthy_percent=100,
min_healthy_percent=0,
security_groups=[userguide_sg],
)
ulb: elb.CfnLoadBalancer = userguide_alb.load_balancer.node.default_child
ulb.access_logging_policy = elb.CfnLoadBalancer.AccessLoggingPolicyProperty(
enabled=True,
s3_bucket_name=logs_bucket.bucket_name,
s3_bucket_prefix='userguide',
)
userguide_alb.target_group.configure_health_check(
port='80',
path='/',
timeout=Duration.seconds(10),
healthy_threshold_count=2,
unhealthy_threshold_count=2,
interval=Duration.seconds(15),
)
self.allow_alb_access(userguide_alb, ip_ranges, vpc)

CfnOutput(
self,
Expand Down
2 changes: 2 additions & 0 deletions deploy/stacks/albfront_stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def __init__(
image_tag=None,
custom_domain=None,
ip_ranges=None,
custom_auth=None,
**kwargs,
):
super().__init__(scope, id, **kwargs)
Expand All @@ -29,6 +30,7 @@ def __init__(
image_tag=image_tag,
custom_domain=custom_domain,
ip_ranges=ip_ranges,
custom_auth=custom_auth
)

Tags.of(albfront_stack).add('Application', f'{resource_prefix}-{envname}')
Expand Down
10 changes: 6 additions & 4 deletions deploy/stacks/lambda_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def __init__(
for claims_map in custom_auth.get('claims_mapping', {}):
custom_lambda_env[claims_map] = custom_auth.get('claims_mapping', '').get(claims_map, '')

authorizerfn_sg = self.create_lambda_sgs(envname, "customauthorizer", resource_prefix, vpc)
authorizer_fn_sg = self.create_lambda_sgs(envname, "customauthorizer", resource_prefix, vpc)
self.authorizer_fn = _lambda.Function(
self,
f'CustomAuthorizerFunction-{envname}',
Expand All @@ -200,9 +200,9 @@ def __init__(
description='dataall Custom authorizer replacing cognito authorizer',
timeout=Duration.seconds(20),
environment=custom_lambda_env,
security_groups=[authorizerfn_sg],
vpc=vpc,
runtime=_lambda.Runtime.PYTHON_3_9,
security_groups=[authorizer_fn_sg],
runtime=_lambda.Runtime.PYTHON_3_9
)

# Add NAT Connectivity For Custom Authorizer Lambda
Expand Down Expand Up @@ -513,6 +513,7 @@ def set_up_graphql_api_gateway(
#Create a custom Authorizer
custom_authorizer_role = iam.Role(self,
f'{resource_prefix}-{envname}-custom-authorizer-role',
role_name=f'{resource_prefix}-{envname}-custom-authorizer-role',
assumed_by=iam.ServicePrincipal("apigateway.amazonaws.com"),
description="Allow Custom Authorizer to call custom auth lambda"
)
Expand All @@ -528,7 +529,8 @@ def set_up_graphql_api_gateway(
handler=self.authorizer_fn,
identity_sources=[apigw.IdentitySource.header('Authorization')],
authorizer_name=f'{resource_prefix}-{envname}-custom-authorizer',
assume_role=custom_authorizer_role
assume_role=custom_authorizer_role,
results_cache_ttl=Duration.minutes(60),
)
if not internet_facing:
if apig_vpce:
Expand Down
109 changes: 79 additions & 30 deletions deploy/stacks/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,39 @@ def validate_deployment_params(self, source, repo_connection_arn, git_branch, re
f'must be less than 50 characters to avoid AWS resources naming limits'
)

# Validate if all configs are present when deploying custom_auth
for env in target_envs:
if 'custom_auth' in env:
custom_auth_configs = env.get('custom_auth')
if ('url' not in custom_auth_configs or
'provider' not in custom_auth_configs or
'redirect_url' not in custom_auth_configs or
'client_id' not in custom_auth_configs or
'response_types' not in custom_auth_configs or
'scopes' not in custom_auth_configs or
'jwks_url' not in custom_auth_configs or
'claims_mapping' not in custom_auth_configs or
'user_id' not in custom_auth_configs['claims_mapping'] or
'email' not in custom_auth_configs['claims_mapping']
):
raise ValueError(
'Custom Auth Configuration Error : Missing some configurations in custom_auth section in Deployments. Please take a look at template_cdk.json for reference or visit the data.all webpage and checkout the Deploy to AWS section'
)

if (not isinstance(custom_auth_configs['url'], str) or
not isinstance(custom_auth_configs['provider'], str) or
not isinstance(custom_auth_configs['redirect_url'], str) or
not isinstance(custom_auth_configs['client_id'], str) or
not isinstance(custom_auth_configs['response_types'], str) or
not isinstance(custom_auth_configs['scopes'], str) or
not isinstance(custom_auth_configs['jwks_url'], str) or
not isinstance(custom_auth_configs['claims_mapping']['user_id'], str) or
not isinstance(custom_auth_configs['claims_mapping']['email'], str)
):
raise TypeError(
'Custom Auth Configuration Error : Type error: Configs type is not as required. Please take a look at template_cdk.json for reference or visit the data.all webpage and checkout the Deploy to AWS section'
)

def set_quality_gate_stage(self):
quality_gate_param = self.node.try_get_context('quality_gate')
if quality_gate_param is not False:
Expand Down Expand Up @@ -636,7 +669,7 @@ def set_backend_stage(self, target_env, repository_name):
apig_vpce=target_env.get('apig_vpce'),
prod_sizing=target_env.get('prod_sizing', True),
quicksight_enabled=target_env.get('enable_quicksight_monitoring', False),
enable_cw_rum=target_env.get('enable_cw_rum', False),
enable_cw_rum=target_env.get('enable_cw_rum', False) and target_env.get("custom_auth", None) == None,
enable_cw_canaries=target_env.get('enable_cw_canaries', False) and target_env.get("custom_auth", None) == None,
shared_dashboard_sessions=target_env.get('shared_dashboard_sessions', 'anonymous'),
enable_opensearch_serverless=target_env.get('enable_opensearch_serverless', False),
Expand Down Expand Up @@ -741,7 +774,7 @@ def set_cloudfront_stage(self, target_env):
f'export internet_facing={target_env.get("internet_facing", True)}',
f'export custom_domain={str(True) if target_env.get("custom_domain") else str(False)}',
f'export deployment_region={target_env.get("region", self.region)}',
f'export enable_cw_rum={target_env.get("enable_cw_rum", False)}',
f'export enable_cw_rum={target_env.get("enable_cw_rum", False) and target_env.get("custom_auth", None) == None }',
f'export resource_prefix={self.resource_prefix}',
f'export reauth_ttl={str(target_env.get("reauth_config", {}).get("ttl", 5))}',
f'export custom_auth_provider={str(target_env.get("custom_auth", {}).get("provider", "None"))}',
Expand Down Expand Up @@ -781,7 +814,7 @@ def set_cloudfront_stage(self, target_env):
*front_stage_actions,
self.cognito_config_action(target_env),
)
if target_env.get('enable_cw_rum', False):
if target_env.get('enable_cw_rum', False) and target_env.get("custom_auth", None) == None:
front_stage_actions = (
*front_stage_actions,
self.cw_rum_config_action(target_env),
Expand Down Expand Up @@ -885,6 +918,7 @@ def set_albfront_stage(self, target_env, repository_name):
custom_domain=target_env['custom_domain'],
ip_ranges=target_env.get('ip_ranges'),
resource_prefix=self.resource_prefix,
custom_auth=target_env.get('custom_auth', None)
),
pre=[
pipelines.CodeBuildStep(
Expand All @@ -907,8 +941,18 @@ def set_albfront_stage(self, target_env, repository_name):
f'export internet_facing={target_env.get("internet_facing", False)}',
f'export custom_domain=True',
f'export deployment_region={target_env.get("region", self.region)}',
f'export enable_cw_rum={target_env.get("enable_cw_rum", False)}',
f'export enable_cw_rum={target_env.get("enable_cw_rum", False) and target_env.get("custom_auth", None) == None}',
f'export resource_prefix={self.resource_prefix}',
f'export reauth_ttl={str(target_env.get("reauth_config", {}).get("ttl", 5))}',
f'export custom_auth_provider={str(target_env.get("custom_auth", {}).get("provider", "None"))}',
f'export custom_auth_url={str(target_env.get("custom_auth", {}).get("url", "None"))}',
f'export custom_auth_redirect_url={str(target_env.get("custom_auth", {}).get("redirect_url", "None"))}',
f'export custom_auth_client_id={str(target_env.get("custom_auth", {}).get("client_id", "None"))}',
f'export custom_auth_response_types={str(target_env.get("custom_auth", {}).get("response_types", "None"))}',
f'export custom_auth_scopes={str(target_env.get("custom_auth", {}).get("scopes", "None"))}',
f'export custom_auth_claims_mapping_email={str(target_env.get("custom_auth", {}).get("claims_mapping", {}).get("email", "None"))}',
f'export custom_auth_claims_mapping_user_id={str(target_env.get("custom_auth", {}).get("claims_mapping", {}).get("user_id", "None"))}',
## Ask can we make the .aws file with a permission of 400
'mkdir ~/.aws/ && touch ~/.aws/config',
'echo "[profile buildprofile]" > ~/.aws/config',
f'echo "role_arn = arn:aws:iam::{target_env["account"]}:role/{self.resource_prefix}-{target_env["envname"]}-cognito-config-role" >> ~/.aws/config',
Expand All @@ -926,39 +970,44 @@ def set_albfront_stage(self, target_env, repository_name):
],
role=self.expanded_codebuild_role.without_policy_updates(),
vpc=self.vpc,
),
pipelines.CodeBuildStep(
id='UserGuideImage',
build_environment=codebuild.BuildEnvironment(
build_image=codebuild.LinuxBuildImage.AMAZON_LINUX_2_4,
compute_type=codebuild.ComputeType.LARGE,
privileged=True,
environment_variables={
'REPOSITORY_URI': codebuild.BuildEnvironmentVariable(
value=f'{self.account}.dkr.ecr.{self.region}.amazonaws.com/{repository_name}'
),
'IMAGE_TAG': codebuild.BuildEnvironmentVariable(value=f'userguide-{self.image_tag}'),
},
),
commands=[
f'aws codeartifact login --tool pip --repository {self.codeartifact.codeartifact_pip_repo_name} --domain {self.codeartifact.codeartifact_domain_name} --domain-owner {self.codeartifact.domain.attr_owner}',
'cd documentation/userguide',
'docker build -f docker/prod/Dockerfile -t $IMAGE_TAG:$IMAGE_TAG .',
f'aws ecr get-login-password --region {self.region} | docker login --username AWS --password-stdin {self.account}.dkr.ecr.{self.region}.amazonaws.com',
'docker tag $IMAGE_TAG:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG',
'docker push $REPOSITORY_URI:$IMAGE_TAG',
],
role=self.expanded_codebuild_role.without_policy_updates(),
vpc=self.vpc,
),
)
]
)
if target_env.get('custom_auth') is None:
albfront_stage.add_pre(self.user_guide_pre_build_alb(repository_name))

if target_env.get('custom_auth') is None:
albfront_stage.add_post(self.cognito_config_action(target_env))

if target_env.get('enable_cw_rum', False):
if target_env.get('enable_cw_rum', False) and target_env.get("custom_auth", None) == None:
albfront_stage.add_post(self.cw_rum_config_action(target_env))

def user_guide_pre_build_alb(self, repository_name):
return pipelines.CodeBuildStep(
id='UserGuideImage',
build_environment=codebuild.BuildEnvironment(
build_image=codebuild.LinuxBuildImage.AMAZON_LINUX_2_4,
compute_type=codebuild.ComputeType.LARGE,
privileged=True,
environment_variables={
'REPOSITORY_URI': codebuild.BuildEnvironmentVariable(
value=f'{self.account}.dkr.ecr.{self.region}.amazonaws.com/{repository_name}'
),
'IMAGE_TAG': codebuild.BuildEnvironmentVariable(value=f'userguide-{self.image_tag}'),
},
),
commands=[
f'aws codeartifact login --tool pip --repository {self.codeartifact.codeartifact_pip_repo_name} --domain {self.codeartifact.codeartifact_domain_name} --domain-owner {self.codeartifact.domain.attr_owner}',
'cd documentation/userguide',
'docker build -f docker/prod/Dockerfile -t $IMAGE_TAG:$IMAGE_TAG .',
f'aws ecr get-login-password --region {self.region} | docker login --username AWS --password-stdin {self.account}.dkr.ecr.{self.region}.amazonaws.com',
'docker tag $IMAGE_TAG:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG',
'docker push $REPOSITORY_URI:$IMAGE_TAG',
],
role=self.expanded_codebuild_role.without_policy_updates(),
vpc=self.vpc,
)

def set_release_stage(
self,
):
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/authentication/components/GuestGuard.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import { Navigate } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';
import { useAuth } from 'authentication';

export const GuestGuard = ({ children }) => {
const { isAuthenticated } = useAuth();
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/authentication/hooks/useToken.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Auth } from 'aws-amplify';
import { useEffect, useState } from 'react';
import { SET_ERROR, useDispatch } from 'globalErrors';
import { useAuth } from './useAuth';
import { useAuth } from 'authentication';

export const useToken = () => {
const dispatch = useDispatch();
Expand Down
Loading

0 comments on commit 6f3aee3

Please sign in to comment.