def _create_user_pool(self) -> cognito.UserPool: pool = cognito.UserPool( scope=self, id="orbit-user-pool", account_recovery=cognito.AccountRecovery.EMAIL_ONLY, auto_verify=cognito.AutoVerifiedAttrs(email=True, phone=False), custom_attributes=None, email_settings=None, lambda_triggers=None, mfa=cognito.Mfa.OFF, mfa_second_factor=None, password_policy=cognito.PasswordPolicy( min_length=8, require_digits=True, require_lowercase=True, require_symbols=True, require_uppercase=True, temp_password_validity=Duration.days(5), ), self_sign_up_enabled=False, sign_in_aliases=cognito.SignInAliases(email=True, phone=False, preferred_username=False, username=True), sign_in_case_sensitive=True, sms_role=None, sms_role_external_id=None, standard_attributes=cognito.StandardAttributes( email=cognito.StandardAttribute(required=True, mutable=True)), user_invitation=cognito.UserInvitationConfig( email_subject="Invite to join Orbit Workbench!", email_body= "Hello, you have been invited to join Orbit Workbench!<br/><br/>" "Username: {username}<br/>" "Temporary password: {####}<br/><br/>" "Regards", ), user_pool_name=f"orbit-{self.env_name}-user-pool", ) pool.apply_removal_policy(policy=core.RemovalPolicy.DESTROY) pool.add_domain( id="orbit-user-pool-domain", cognito_domain=cognito.CognitoDomainOptions( domain_prefix=f"orbit-{self.context.account_id}-{self.env_name}" ), ) return pool
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) with open("stack/config.yml", 'r') as stream: configs = yaml.safe_load(stream) ### S3 core images_S3_bucket = _s3.Bucket(self, "ICS_IMAGES") images_S3_bucket.add_cors_rule( allowed_methods=[_s3.HttpMethods.POST], allowed_origins=["*"] # add API gateway web resource URL ) ### SQS core image_deadletter_queue = _sqs.Queue(self, "ICS_IMAGES_DEADLETTER_QUEUE") image_queue = _sqs.Queue(self, "ICS_IMAGES_QUEUE", dead_letter_queue={ "max_receive_count": configs["DeadLetterQueue"]["MaxReceiveCount"], "queue": image_deadletter_queue }) ### api gateway core api_gateway = RestApi(self, 'ICS_API_GATEWAY', rest_api_name='ImageContentSearchApiGateway') api_gateway_resource = api_gateway.root.add_resource(configs["ProjectName"]) api_gateway_landing_page_resource = api_gateway_resource.add_resource('web') api_gateway_get_signedurl_resource = api_gateway_resource.add_resource('signedUrl') api_gateway_image_search_resource = api_gateway_resource.add_resource('search') ### landing page function get_landing_page_function = Function(self, "ICS_GET_LANDING_PAGE", function_name="ICS_GET_LANDING_PAGE", runtime=Runtime.PYTHON_3_7, handler="main.handler", code=Code.asset("./src/landingPage")) get_landing_page_integration = LambdaIntegration( get_landing_page_function, proxy=True, integration_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': "'*'", } }]) api_gateway_landing_page_resource.add_method('GET', get_landing_page_integration, method_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': True, } }]) ### cognito required_attribute = _cognito.StandardAttribute(required=True) users_pool = _cognito.UserPool(self, "ICS_USERS_POOL", auto_verify=_cognito.AutoVerifiedAttrs(email=True), #required for self sign-up standard_attributes=_cognito.StandardAttributes(email=required_attribute), #required for self sign-up self_sign_up_enabled=configs["Cognito"]["SelfSignUp"]) user_pool_app_client = _cognito.CfnUserPoolClient(self, "ICS_USERS_POOL_APP_CLIENT", supported_identity_providers=["COGNITO"], allowed_o_auth_flows=["implicit"], allowed_o_auth_scopes=configs["Cognito"]["AllowedOAuthScopes"], user_pool_id=users_pool.user_pool_id, callback_ur_ls=[api_gateway_landing_page_resource.url], allowed_o_auth_flows_user_pool_client=True, explicit_auth_flows=["ALLOW_REFRESH_TOKEN_AUTH"]) user_pool_domain = _cognito.UserPoolDomain(self, "ICS_USERS_POOL_DOMAIN", user_pool=users_pool, cognito_domain=_cognito.CognitoDomainOptions(domain_prefix=configs["Cognito"]["DomainPrefix"])) ### get signed URL function get_signedurl_function = Function(self, "ICS_GET_SIGNED_URL", function_name="ICS_GET_SIGNED_URL", environment={ "ICS_IMAGES_BUCKET": images_S3_bucket.bucket_name, "DEFAULT_SIGNEDURL_EXPIRY_SECONDS": configs["Functions"]["DefaultSignedUrlExpirySeconds"] }, runtime=Runtime.PYTHON_3_7, handler="main.handler", code=Code.asset("./src/getSignedUrl")) get_signedurl_integration = LambdaIntegration( get_signedurl_function, proxy=True, integration_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': "'*'", } }]) api_gateway_get_signedurl_authorizer = CfnAuthorizer(self, "ICS_API_GATEWAY_GET_SIGNED_URL_AUTHORIZER", rest_api_id=api_gateway_get_signedurl_resource.rest_api.rest_api_id, name="ICS_API_GATEWAY_GET_SIGNED_URL_AUTHORIZER", type="COGNITO_USER_POOLS", identity_source="method.request.header.Authorization", provider_arns=[users_pool.user_pool_arn]) api_gateway_get_signedurl_resource.add_method('GET', get_signedurl_integration, authorization_type=AuthorizationType.COGNITO, method_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': True, } }] ).node.find_child('Resource').add_property_override('AuthorizerId', api_gateway_get_signedurl_authorizer.ref) images_S3_bucket.grant_put(get_signedurl_function, objects_key_pattern="new/*") ### image massage function image_massage_function = Function(self, "ICS_IMAGE_MASSAGE", function_name="ICS_IMAGE_MASSAGE", timeout=core.Duration.seconds(6), runtime=Runtime.PYTHON_3_7, environment={"ICS_IMAGE_MASSAGE": image_queue.queue_name}, handler="main.handler", code=Code.asset("./src/imageMassage")) images_S3_bucket.grant_write(image_massage_function, "processed/*") images_S3_bucket.grant_delete(image_massage_function, "new/*") images_S3_bucket.grant_read(image_massage_function, "new/*") new_image_added_notification = _s3notification.LambdaDestination(image_massage_function) images_S3_bucket.add_event_notification(_s3.EventType.OBJECT_CREATED, new_image_added_notification, _s3.NotificationKeyFilter(prefix="new/") ) image_queue.grant_send_messages(image_massage_function) ### image analyzer function image_analyzer_function = Function(self, "ICS_IMAGE_ANALYSIS", function_name="ICS_IMAGE_ANALYSIS", runtime=Runtime.PYTHON_3_7, timeout=core.Duration.seconds(10), environment={ "ICS_IMAGES_BUCKET": images_S3_bucket.bucket_name, "DEFAULT_MAX_CALL_ATTEMPTS": configs["Functions"]["DefaultMaxApiCallAttempts"], "REGION": core.Aws.REGION, }, handler="main.handler", code=Code.asset("./src/imageAnalysis")) image_analyzer_function.add_event_source(_lambda_event_source.SqsEventSource(queue=image_queue, batch_size=10)) image_queue.grant_consume_messages(image_massage_function) lambda_rekognition_access = _iam.PolicyStatement( effect=_iam.Effect.ALLOW, actions=["rekognition:DetectLabels", "rekognition:DetectModerationLabels"], resources=["*"] ) image_analyzer_function.add_to_role_policy(lambda_rekognition_access) images_S3_bucket.grant_read(image_analyzer_function, "processed/*") ### API gateway finalizing self.add_cors_options(api_gateway_get_signedurl_resource) self.add_cors_options(api_gateway_landing_page_resource) self.add_cors_options(api_gateway_image_search_resource) ### database database_secret = _secrets_manager.Secret(self, "ICS_DATABASE_SECRET", secret_name="rds-db-credentials/image-content-search-rds-secret", generate_secret_string=_secrets_manager.SecretStringGenerator( generate_string_key='password', secret_string_template='{"username": "******"}', exclude_punctuation=True, exclude_characters='/@\" \\\'', require_each_included_type=True ) ) database = _rds.CfnDBCluster(self, "ICS_DATABASE", engine=_rds.DatabaseClusterEngine.aurora_mysql(version=_rds.AuroraMysqlEngineVersion.VER_5_7_12).engine_type, engine_mode="serverless", database_name=configs["Database"]["Name"], enable_http_endpoint=True, deletion_protection=configs["Database"]["DeletionProtection"], master_username=database_secret.secret_value_from_json("username").to_string(), master_user_password=database_secret.secret_value_from_json("password").to_string(), scaling_configuration=_rds.CfnDBCluster.ScalingConfigurationProperty( auto_pause=configs["Database"]["Scaling"]["AutoPause"], min_capacity=configs["Database"]["Scaling"]["Min"], max_capacity=configs["Database"]["Scaling"]["Max"], seconds_until_auto_pause=configs["Database"]["Scaling"]["SecondsToAutoPause"] ), ) database_cluster_arn = "arn:aws:rds:{}:{}:cluster:{}".format(core.Aws.REGION, core.Aws.ACCOUNT_ID, database.ref) secret_target = _secrets_manager.CfnSecretTargetAttachment(self,"ICS_DATABASE_SECRET_TARGET", target_type="AWS::RDS::DBCluster", target_id=database.ref, secret_id=database_secret.secret_arn ) secret_target.node.add_dependency(database) ### database function image_data_function_role = _iam.Role(self, "ICS_IMAGE_DATA_FUNCTION_ROLE", role_name="ICS_IMAGE_DATA_FUNCTION_ROLE", assumed_by=_iam.ServicePrincipal("lambda.amazonaws.com"), managed_policies=[ _iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaVPCAccessExecutionRole"), _iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaBasicExecutionRole"), _iam.ManagedPolicy.from_aws_managed_policy_name("AmazonRDSDataFullAccess") ] ) image_data_function = Function(self, "ICS_IMAGE_DATA", function_name="ICS_IMAGE_DATA", runtime=Runtime.PYTHON_3_7, timeout=core.Duration.seconds(5), role=image_data_function_role, environment={ "DEFAULT_MAX_CALL_ATTEMPTS": configs["Functions"]["DefaultMaxApiCallAttempts"], "CLUSTER_ARN": database_cluster_arn, "CREDENTIALS_ARN": database_secret.secret_arn, "DB_NAME": database.database_name, "REGION": core.Aws.REGION }, handler="main.handler", code=Code.asset("./src/imageData") ) image_search_integration = LambdaIntegration( image_data_function, proxy=True, integration_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': "'*'", } }]) api_gateway_image_search_authorizer = CfnAuthorizer(self, "ICS_API_GATEWAY_IMAGE_SEARCH_AUTHORIZER", rest_api_id=api_gateway_image_search_resource.rest_api.rest_api_id, name="ICS_API_GATEWAY_IMAGE_SEARCH_AUTHORIZER", type="COGNITO_USER_POOLS", identity_source="method.request.header.Authorization", provider_arns=[users_pool.user_pool_arn]) api_gateway_image_search_resource.add_method('POST', image_search_integration, authorization_type=AuthorizationType.COGNITO, method_responses=[{ 'statusCode': '200', 'responseParameters': { 'method.response.header.Access-Control-Allow-Origin': True, } }] ).node.find_child('Resource').add_property_override('AuthorizerId', api_gateway_image_search_authorizer.ref) lambda_access_search = _iam.PolicyStatement( effect=_iam.Effect.ALLOW, actions=["translate:TranslateText"], resources=["*"] ) image_data_function.add_to_role_policy(lambda_access_search) ### custom resource lambda_provider = Provider(self, 'ICS_IMAGE_DATA_PROVIDER', on_event_handler=image_data_function ) core.CustomResource(self, 'ICS_IMAGE_DATA_RESOURCE', service_token=lambda_provider.service_token, pascal_case_properties=False, resource_type="Custom::SchemaCreation", properties={ "source": "Cloudformation" } ) ### event bridge event_bus = _events.EventBus(self, "ICS_IMAGE_CONTENT_BUS") event_rule = _events.Rule(self, "ICS_IMAGE_CONTENT_RULE", rule_name="ICS_IMAGE_CONTENT_RULE", description="The event from image analyzer to store the data", event_bus=event_bus, event_pattern=_events.EventPattern(resources=[image_analyzer_function.function_arn]), ) event_rule.add_target(_event_targets.LambdaFunction(image_data_function)) event_bus.grant_put_events(image_analyzer_function) image_analyzer_function.add_environment("EVENT_BUS", event_bus.event_bus_name) ### outputs core.CfnOutput(self, 'CognitoHostedUILogin', value='https://{}.auth.{}.amazoncognito.com/login?client_id={}&response_type=token&scope={}&redirect_uri={}'.format(user_pool_domain.domain_name, core.Aws.REGION, user_pool_app_client.ref, '+'.join(user_pool_app_client.allowed_o_auth_scopes), api_gateway_landing_page_resource.url), description='The Cognito Hosted UI Login Page' )
def __init__(self, scope: cdk.Construct, id: str, domain_name: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # User pool and user pool OAuth client cognito_user_pool = cognito.UserPool( self, "UserPool", removal_policy=cdk.RemovalPolicy.DESTROY) cognito.UserPoolDomain( self, "UserPoolDomain", cognito_domain=cognito.CognitoDomainOptions( domain_prefix=APPLICATION_PREFIX + "-" + APPLICATION_SUFFIX), user_pool=cognito_user_pool, ) cognito_admin_user = cr.AwsCustomResource( self, "UserPoolAdminUserResource", policy=cr.AwsCustomResourcePolicy.from_sdk_calls( resources=cr.AwsCustomResourcePolicy.ANY_RESOURCE), on_create=cr.AwsSdkCall( service="CognitoIdentityServiceProvider", action="adminCreateUser", parameters={ "UserPoolId": cognito_user_pool.user_pool_id, "Username": "******", "UserAttributes": [{ "Name": "email", "Value": "consoleme_admin@" + domain_name }], "TemporaryPassword": ADMIN_TEMP_PASSWORD, }, physical_resource_id=cr.PhysicalResourceId.of( cognito_user_pool.user_pool_id), ), ) cognito_admin_group = cr.AwsCustomResource( self, "UserPoolAdminGroupResource", policy=cr.AwsCustomResourcePolicy.from_sdk_calls( resources=cr.AwsCustomResourcePolicy.ANY_RESOURCE), on_create=cr.AwsSdkCall( service="CognitoIdentityServiceProvider", action="createGroup", parameters={ "UserPoolId": cognito_user_pool.user_pool_id, "GroupName": "consoleme_admins", }, physical_resource_id=cr.PhysicalResourceId.of( id="UserPoolAdminGroupResource"), ), ) cr.AwsCustomResource( self, "UserPoolUserGroupResource", policy=cr.AwsCustomResourcePolicy.from_sdk_calls( resources=cr.AwsCustomResourcePolicy.ANY_RESOURCE), on_create=cr.AwsSdkCall( service="CognitoIdentityServiceProvider", action="createGroup", parameters={ "UserPoolId": cognito_user_pool.user_pool_id, "GroupName": "consoleme_users", }, physical_resource_id=cr.PhysicalResourceId.of( id="UserPoolUserGroupResource"), ), ) cognito_assign_admin_group = cr.AwsCustomResource( self, "UserPoolAssignAdminGroupResource", policy=cr.AwsCustomResourcePolicy.from_sdk_calls( resources=cr.AwsCustomResourcePolicy.ANY_RESOURCE), on_create=cr.AwsSdkCall( service="CognitoIdentityServiceProvider", action="adminAddUserToGroup", parameters={ "UserPoolId": cognito_user_pool.user_pool_id, "GroupName": "consoleme_admins", "Username": "******", }, physical_resource_id=cr.PhysicalResourceId.of( id="UserPoolAssignAdminGroupResource"), ), ) cognito_assign_admin_group.node.add_dependency(cognito_admin_user) cognito_assign_admin_group.node.add_dependency(cognito_admin_group) self.cognito_user_pool = cognito_user_pool
def add_cognito(self): """ Sets up the cognito infrastructure with the user pool, custom domain and app client for use by the ALB. """ # Create the user pool that holds our users self.user_pool = cognito.UserPool( self, "user-pool", account_recovery=cognito.AccountRecovery. EMAIL_AND_PHONE_WITHOUT_MFA, auto_verify=cognito.AutoVerifiedAttrs(email=True, phone=True), self_sign_up_enabled=True, standard_attributes=cognito.StandardAttributes( email=cognito.StandardAttribute(mutable=True, required=True), given_name=cognito.StandardAttribute(mutable=True, required=True), family_name=cognito.StandardAttribute(mutable=True, required=True))) # Add a lambda function that automatically confirms new users without # email/phone verification, just for this demo auto_confirm_function = _lambda.Function( self, "auto-confirm-function", code=_lambda.Code.from_asset(path=os.path.join( os.path.dirname(__file__), "..", "auto_confirm_function")), handler="lambda_handler.lambda_handler", runtime=_lambda.Runtime.PYTHON_3_8, ) self.user_pool.add_trigger( operation=cognito.UserPoolOperation.PRE_SIGN_UP, fn=auto_confirm_function) # Add a custom domain for the hosted UI self.user_pool_custom_domain = self.user_pool.add_domain( "user-pool-domain", cognito_domain=cognito.CognitoDomainOptions( domain_prefix=self.config.cognito_custom_domain)) # Create an app client that the ALB can use for authentication self.user_pool_client = self.user_pool.add_client( "alb-app-client", user_pool_client_name="AlbAuthentication", generate_secret=True, o_auth=cognito.OAuthSettings( callback_urls=[ # This is the endpoint where the ALB accepts the # response from Cognito f"https://{self.config.application_dns_name}/oauth2/idpresponse", # This is here to allow a redirect to the login page # after the logout has been completed f"https://{self.config.application_dns_name}" ], flows=cognito.OAuthFlows(authorization_code_grant=True), scopes=[cognito.OAuthScope.OPENID]), supported_identity_providers=[ cognito.UserPoolClientIdentityProvider.COGNITO ]) # Logout URLs and redirect URIs can't be set in CDK constructs natively ...yet user_pool_client_cf: cognito.CfnUserPoolClient = self.user_pool_client.node.default_child user_pool_client_cf.logout_ur_ls = [ # This is here to allow a redirect to the login page # after the logout has been completed f"https://{self.config.application_dns_name}" ] self.user_pool_full_domain = self.user_pool_custom_domain.base_url() redirect_uri = urllib.parse.quote('https://' + self.config.application_dns_name) self.user_pool_logout_url = f"{self.user_pool_full_domain}/logout?" \ + f"client_id={self.user_pool_client.user_pool_client_id}&" \ + f"logout_uri={redirect_uri}" self.user_pool_user_info_url = f"{self.user_pool_full_domain}/oauth2/userInfo"
def __init__(self, scope: core.Construct, id: str, cognito_domain_name: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here): svc_name = self.node.try_get_context("service_name") url_name = core.CfnParameter( self, id="cognitoDomainName", description="Enter the name the domain you want to use", type="String", default="mystique") # Create an Identity Pool self.unicorn_user_pool = _cognito.UserPool( self, "unicornUserPool", user_pool_name="Miztiik-Unicorn-App-User-Pool", # sign_in_aliases={"username": True,"email": True} sign_in_aliases=_cognito.SignInAliases(username=True, email=True), standard_attributes={ "email": { "required": True, "mutable": False }, "fullname": { "required": False, "mutable": True } }, auto_verify=_cognito.AutoVerifiedAttrs(email=True)) # OAuth Scopes self.unicorn_user_pool_res_srv_identifier = f"premium_api" self.unicorn_read_scope = f"read" self.unicorn_write_scope = f"write" unicorn_users_auth_domain = _cognito.UserPoolDomain( self, "userPoolDomain", user_pool=self.unicorn_user_pool, cognito_domain=_cognito.CognitoDomainOptions( domain_prefix=f"{cognito_domain_name}")) self.unicorn_user_pool.user_pool_arn user_pool_res_srv = _cognito.CfnUserPoolResourceServer( self, "ResourceServer", # Having URL format is recommended # identifier=f"{premium_content.url}", identifier=f"{self.unicorn_user_pool_res_srv_identifier}", name=f"premium-api-authorizer", user_pool_id=self.unicorn_user_pool.user_pool_id, scopes=[{ "scopeName": f"{self.unicorn_read_scope}", "scopeDescription": "Get Premium Api Content" }, { "scopeName": f"{self.unicorn_write_scope}", "scopeDescription": "Put Premium Api Content" }]) user_pool_client = _cognito.UserPoolClient( self, "AppClient", user_pool=self.unicorn_user_pool, user_pool_client_name="premium_app_users", generate_secret=True, # We'll allow both Flows, Implicit and Authorization Code, and decide in the app which to use. auth_flows=_cognito.AuthFlow(admin_user_password=False, custom=True, refresh_token=True, user_password=False, user_srp=True), prevent_user_existence_errors=True, o_auth=_cognito.OAuthSettings( flows=_cognito.OAuthFlows(authorization_code_grant=False, implicit_code_grant=False, client_credentials=True), scopes=[ # _cognito.OAuthScope.EMAIL, # _cognito.OAuthScope.OPENID, # _cognito.OAuthScope.COGNITO_ADMIN, # _cognito.OAuthScope.PROFILE, # https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_cognito/OAuthScope.html#aws_cdk.aws_cognito.OAuthScope _cognito.OAuthScope.custom( f"{self.unicorn_user_pool_res_srv_identifier}/{self.unicorn_read_scope}" ), _cognito.OAuthScope.custom( f"{self.unicorn_user_pool_res_srv_identifier}/{self.unicorn_write_scope}" ) ])) # Add dependency so that ResourceServer is deployed before App Client user_pool_client.node.add_dependency(user_pool_res_srv) # Retrieve Cognito App Client Secret and Add to Secrets Manager app_secrets = CognitoAppClientSecretRetrieverStack( self, "appClientSecrets", user_pool_id=self.unicorn_user_pool.user_pool_id, user_pool_client_id=user_pool_client.user_pool_client_id, user_pool_oauth2_endpoint= f"https://{unicorn_users_auth_domain.domain_name}.auth.{core.Aws.REGION}.amazoncognito.com/oauth2/token", unicorn_user_pool_res_srv_identifier= f"{self.unicorn_user_pool_res_srv_identifier}", unicorn_read_scope=f"{self.unicorn_read_scope}", unicorn_write_scope=f"{self.unicorn_write_scope}") # Export Value self.unicorn_user_pool_secrets_arn = app_secrets.response ########################################### ################# OUTPUTS ################# ########################################### output_0 = core.CfnOutput( self, "AutomationFrom", value=f"{global_args.SOURCE_INFO}", description= "To know more about this automation stack, check out our github page." ) # https://AUTH_DOMAIN/oauth2/token output_1 = core.CfnOutput( self, "UnicornIdentityAuthDomain", value= f"https://{unicorn_users_auth_domain.domain_name}.auth.{core.Aws.REGION}.amazoncognito.com/oauth2/token", description="Authenticate Against this endpoint") output_2 = core.CfnOutput(self, "AppPoolSecretsArn", value=f"{app_secrets.response}", description="AppPoolSecretsArn")
def __init__(self, scope: core.Construct, construct_id: str, cognito_prefix: str, stack_log_level: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # The code that defines your stack goes here # Cognito User Pool for Kibana Access self.es_user_pool = _cognito.UserPool( self, "esCognitoUserPool", user_pool_name=f"{cognito_prefix}-log-parser-es-users", self_sign_up_enabled=False, sign_in_aliases=_cognito.SignInAliases(username=True, email=True), sign_in_case_sensitive=False, standard_attributes={ "email": { "required": True, "mutable": False }, "fullname": { "required": False, "mutable": True } }, password_policy=_cognito.PasswordPolicy(min_length=8), auto_verify=_cognito.AutoVerifiedAttrs(email=True)) # Create User Pool Domain to enable SignUp, SignIn, Auth & Callback Urls es_auth_domain = _cognito.UserPoolDomain( self, "esCognitoUserPoolDomain", user_pool=self.es_user_pool, cognito_domain=_cognito.CognitoDomainOptions( domain_prefix=f"{cognito_prefix}-{core.Aws.ACCOUNT_ID}")) # Role Authenticated Cognito Users will assume in ES Service self.es_role = _iam.Role( self, "esKibanaIamRole", assumed_by=_iam.ServicePrincipal("es.amazonaws.com"), managed_policies=[ _iam.ManagedPolicy.from_aws_managed_policy_name( managed_policy_name="AmazonESCognitoAccess") ], ) # Create Cognito Federated Identity Pool to exchange Cognito auth token for AWS Token self.es_id_pool = _cognito.CfnIdentityPool( self, "esIdentityPool", allow_unauthenticated_identities=False, cognito_identity_providers=[], ) # Role For Cognito Federated Idenity Pool Authenticated Users self.es_auth_role = _iam.Role( self, "esAuthIamRole", assumed_by=_iam.FederatedPrincipal( federated="cognito-identity.amazonaws.com", conditions={ "StringEquals": { "cognito-identity.amazonaws.com:aud": self.es_id_pool.ref }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" }, }, assume_role_action="sts:AssumeRoleWithWebIdentity"), ) # Attach a Role to Cognito Federated Idenity Pool Authenticated Users _cognito.CfnIdentityPoolRoleAttachment( self, "cognitoFederatedIdentityPoolRoleAttachment", identity_pool_id=self.es_id_pool.ref, roles={"authenticated": self.es_auth_role.role_arn}) ########################################### ################# OUTPUTS ################# ########################################### output_0 = core.CfnOutput( self, "AutomationFrom", value=f"{GlobalArgs.SOURCE_INFO}", description= "To know more about this automation stack, check out our github page." ) output_1 = core.CfnOutput( self, "CreateCognitoUserConsole", value= f"https://{core.Aws.REGION}.console.aws.amazon.com/cognito/users?region={core.Aws.REGION}#/pool/{self.es_user_pool.user_pool_id}/users", description="Create a new user in the user pool here.")