Example #1
0
    def create_user_pool_client(
        self, user_pool: aws_cognito.CfnUserPool, tag: str, include_federation: bool
    ) -> aws_cognito.CfnUserPoolClient:
        if not include_federation:
            user_pool_client = aws_cognito.CfnUserPoolClient(
                self, f"userpool_client_{tag}", generate_secret=True, user_pool_id=user_pool.ref,
            )
            return user_pool_client

        user_pool_client = aws_cognito.CfnUserPoolClient(
            self,
            f"userpool_client_{tag}",
            generate_secret=True,
            user_pool_id=user_pool.ref,
            allowed_o_auth_flows=["code"],
            allowed_o_auth_flows_user_pool_client=True,
            allowed_o_auth_scopes=[
                "phone",
                "email",
                "openid",
                "profile",
                "aws.cognito.signin.user.admin",
            ],
            callback_ur_ls=[self._secrets["hostedui.sign_in_redirect"]],
            logout_ur_ls=[self._secrets["hostedui.sign_out_redirect"]],
            explicit_auth_flows=[
                "ALLOW_CUSTOM_AUTH",
                "ALLOW_USER_SRP_AUTH",
                "ALLOW_REFRESH_TOKEN_AUTH",
            ],
            prevent_user_existence_errors="LEGACY",
            supported_identity_providers=["COGNITO", "Facebook", "Google"],
        )
        return user_pool_client
Example #2
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        user_pool = cognito.CfnUserPool(self,
                                        'msa',
                                        auto_verified_attributes=['email'],
                                        username_attributes=['email'],
                                        user_pool_name='msa-user-pool',
                                        schema=[{
                                            'attributeDataType': 'String',
                                            'name': 'custom:tenant_id',
                                            'mutable': True
                                        }, {
                                            'attributeDataType': 'String',
                                            'name': 'role',
                                            'mutable': True
                                        }, {
                                            'attributeDataType': 'String',
                                            'name': 'restrictions',
                                            'mutable': True
                                        }])

        user_pool_client = cognito.CfnUserPoolClient(
            self,
            'pool-client',
            user_pool_id=user_pool.ref,
            client_name='msa-user-client')
        '''
Example #3
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        prj_name = self.node.try_get_context("project_name")
        env_name = self.node.try_get_context("env")

        user_pool = cognito.CfnUserPool(
            self,
            'cognitouserpool',
            auto_verified_attributes=['email'],
            username_attributes=['email', 'phone_number'],
            user_pool_name=prj_name + '-user-pool',
            schema=[{
                'attributeDataType': 'String',
                'name': 'param1',
                'mutable': True
            }],
            policies=cognito.CfnUserPool.PoliciesProperty(
                password_policy=cognito.CfnUserPool.PasswordPolicyProperty(
                    minimum_length=10,
                    require_lowercase=True,
                    require_numbers=True,
                    require_symbols=False,
                    require_uppercase=True)))

        user_pool_client = cognito.CfnUserPoolClient(
            self,
            'pool-client',
            user_pool_id=user_pool.ref,
            client_name=env_name + '-app-client')

        identity_pool = cognito.CfnIdentityPool(
            self,
            'identitypool',
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[
                cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
                    client_id=user_pool_client.ref,
                    provider_name=user_pool.attr_provider_name)
            ],
            identity_pool_name=prj_name + '-identity-pool')

        ssm.StringParameter(self,
                            'app-id',
                            parameter_name='/' + env_name +
                            '/cognito-app-client-id',
                            string_value=user_pool_client.ref)

        ssm.StringParameter(self,
                            'user-pool-id',
                            parameter_name='/' + env_name +
                            '/cognito-user-pool-id',
                            string_value=user_pool_client.user_pool_id)

        ssm.StringParameter(self,
                            'identity-pool-id',
                            parameter_name='/' + env_name +
                            '/cognito-identity-pool-id',
                            string_value=identity_pool.ref)
Example #4
0
    def create_user_pool_client(
        self,
        user_pool: aws_cognito.CfnUserPool,
        tag: str,
        federation_providers: List[aws_cognito.CfnUserPoolIdentityProvider],
    ) -> aws_cognito.CfnUserPoolClient:
        if not federation_providers:
            user_pool_client = aws_cognito.CfnUserPoolClient(
                self,
                f"userpool_client_{tag}",
                generate_secret=True,
                user_pool_id=user_pool.ref,
            )
            return user_pool_client

        user_pool_client = aws_cognito.CfnUserPoolClient(
            self,
            f"userpool_client_{tag}",
            generate_secret=True,
            user_pool_id=user_pool.ref,
            allowed_o_auth_flows=["code"],
            allowed_o_auth_flows_user_pool_client=True,
            allowed_o_auth_scopes=[
                "phone",
                "email",
                "openid",
                "profile",
                "aws.cognito.signin.user.admin",
            ],
            callback_ur_ls=[self._secrets["hostedui.sign_in_redirect"]],
            logout_ur_ls=[self._secrets["hostedui.sign_out_redirect"]],
            explicit_auth_flows=[
                "ALLOW_CUSTOM_AUTH",
                "ALLOW_USER_SRP_AUTH",
                "ALLOW_REFRESH_TOKEN_AUTH",
            ],
            prevent_user_existence_errors="LEGACY",
            supported_identity_providers=["COGNITO", "Facebook", "Google"],
        )

        # Ensure the federation provider dependency is explicit, so lets the provider setup complete
        # before attempting to create the user pool client.
        for provider in federation_providers:
            user_pool_client.node.add_dependency(provider)

        return user_pool_client
    def __init__(self, scope: core.Construct, id: str,
                 props: CognitoUserPoolProps) -> None:
        super().__init__(scope, id)

        # Create L1 user pool

        if "phone_number" in props.auto_verified_attributes:
            sns_role = iam.Role(
                # Role to allow Cognitio to send SNS (SMS) messages
                self,
                "SNSRole",
                assumed_by=iam.ServicePrincipal("cognito-idp.amazonaws.com"),
                inline_policies=[
                    iam.PolicyDocument(statements=[
                        iam.PolicyStatement(actions=["sns:Publish"],
                                            resources=["*"])
                    ])
                ],
            )

            user_pool = cognito.CfnUserPool(
                self,
                "UserPool",
                alias_attributes=props.alias_attributes,
                auto_verified_attributes=props.auto_verified_attributes,
                user_pool_name=props._user_pool_name,
                schema=props._schema,
                policies=props._policies,
                sms_configuration=cognito.CfnUserPool.SmsConfigurationProperty(
                    external_id=props.user_pool_name + "-external",
                    sns_caller_arn=sns_role.role_arn,
                ),
            )
        else:
            # Email verification, SMS config not needed
            user_pool = cognito.CfnUserPool(
                self,
                "UserPool",
                alias_attributes=props.alias_attributes,
                auto_verified_attributes=props.auto_verified_attributes,
                user_pool_name=props._user_pool_name,
                schema=props._schema,
                policies=props._policies,
                username_attributes=props._username_attributes,
            )

        user_pool_client = cognito.CfnUserPoolClient(
            self,
            "UserPoolClient",
            user_pool_id=user_pool.ref,
            client_name=props._client_name,
            generate_secret=False,
            refresh_token_validity=30,
        )
        self.user_pool = user_pool
        self.user_pool_id = user_pool.ref
        self.user_pool_arn = user_pool.attr_arn
        self.client_id = user_pool_client.ref
        self.provider_name = user_pool.attr_provider_name
        core.CfnOutput(
            self,
            "CognitoUserPoolId",
            export_name="CognitoUserPoolId",
            value=user_pool.ref,
        )
        core.CfnOutput(
            self,
            "CognitoUserPoolIdArn",
            export_name="CognitoUserPoolIdArn",
            value=user_pool.attr_arn,
        )
        core.CfnOutput(
            self,
            "CognitoClientId",
            export_name="CognitoClientId",
            value=user_pool_client.ref,
        )
Example #6
0
    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: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Parameters
        parameters = core.CfnParameter(
            self, "SourceBucket",
            description="Building on AWS Cognito Stack Modified https://github.com/rosberglinhares/CloudFormationCognitoCustomResources",
            default="default"
        )

        LogoutURL = core.CfnParameter(
            self, "LogoutURL",
            type="String",
            default="http://localhost"
        )

        CallbackURL = core.CfnParameter(
            self, "CallbackURL",
            type="String",
            default="http://localhost/callback"
        )

        AppDomain = core.CfnParameter(
            self, "AppDomain",
            type="String",
            default="default"
        )
        
        # CognitoSNSPolicy
        CognitoSNSPolicy = iam.CfnManagedPolicy(
            self, 'CognitoSNSPolicy',
            description='Managed policy to allow Amazon Cognito to access SNS',
            policy_document={
                "Version": "2012-10-17",
                "Statement": {
                    "Effect": "Allow",
                    "Action": ["sns:publish"],
                    "Resource": "*"
                }
            })

        # SNSRole
        SNSRole = iam.CfnRole(
            self, "SNSRole",
            role_name="SNSRole",
            managed_policy_arns=[CognitoSNSPolicy.ref],
            assume_role_policy_document={
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Action": ["sts:AssumeRole"],
                        "Principal": {"Service": ["cognito-idp.amazonaws.com"]}
                    }]
            }
        )
        SNSRole.add_depends_on(CognitoSNSPolicy)

        # CognitoUserPool
        CognitoUserPool = cognito.CfnUserPool(
            self, 'UserPool',
            user_pool_name='photos-pool',
            alias_attributes=[
                "email", "phone_number"],
            auto_verified_attributes=[
                "email"],
            email_verification_message="Hi, Your verification code is <br/>{####}\n",
            email_verification_subject="EDX Email Verification",
            mfa_configuration="OPTIONAL",
            policies={
                "passwordPolicy": {
                    "minimumLength": 8,
                    "requireLowercase": True,
                    "requireNumbers": True,
                    "requireSymbols": True,
                    "requireUppercase": True
                }
            },
            schema=[{
                "attributeDataType": "String",
                "mutable": False,
                "name": "nickname",
                "required": True
            },
                {
                "attributeDataType": "String",
                "mutable": False,
                "name": "email",
                "required": True
            },
                {
                "attributeDataType": "String",
                "mutable": False,
                "name": "phone_number",
                "required": True
            }],
            sms_configuration={
                "externalId": "%s-external" % (core.Aws.STACK_NAME),
                "snsCallerArn": SNSRole.attr_arn
            }
        )

        # CognitoUserPoolClient
        CognitoUserPoolClient = cognito.CfnUserPoolClient(
            self, "UserPoolClient",
            client_name="WebsiteClient",
            generate_secret=True,
            user_pool_id=CognitoUserPool.ref
        )

        # CognitoCustomResourceRole
        CustomResourceRole = iam.CfnRole(
            self, "CustomResourceRole",
            role_name="cognito-resource-role",
            assume_role_policy_document={
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Service": [
                                "lambda.amazonaws.com"
                            ]
                        },
                        "Action": [
                            "sts:AssumeRole"
                        ]
                    }
                ]
            },
            policies=[
                {
                    "policyName": "writeCloudWatchLogs",
                    "policyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": "logs:CreateLogGroup",
                                "Resource": "arn:aws:logs:*:*:*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": "logs:CreateLogStream",
                                "Resource": "arn:aws:logs:*:*:*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": "logs:PutLogEvents",
                                "Resource": "arn:aws:logs:*:*:*"
                            }
                        ]
                    }
                },
                {
                    "policyName": "updateUserPoolClient",
                    "policyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": "cognito-idp:UpdateUserPoolClient",
                                "Resource": "arn:aws:cognito-idp:*:*:userpool/*"
                            }
                        ]
                    }
                },
                {
                    "policyName": "manageUserPoolDomain",
                    "policyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": "cognito-idp:CreateUserPoolDomain",
                                "Resource": "arn:aws:cognito-idp:*:*:userpool/*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": "cognito-idp:DeleteUserPoolDomain",
                                "Resource": "arn:aws:cognito-idp:*:*:userpool/*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": "cognito-idp:DescribeUserPoolDomain",
                                "Resource": "*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": "cognito-idp:DescribeUserPoolClient",
                                "Resource": "*"
                            }
                        ]
                    }
                },
                {
                    "policyName": "invokeLambdaFunction",
                    "policyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": "lambda:InvokeFunction",
                                "Resource": "arn:aws:lambda:*:*:function:*"
                            }
                        ]
                    }
                },
            ]
        )

        # CognitoUserPoolClientClientSettings
        with open("./cdk/CognitoUserPoolClientClientSettings/index.js", encoding="utf-8") as fp:
            code_body = fp.read()

        CognitoUserPoolClientClientSettings = cfn.CustomResource(
            self, "CognitoUserPoolClientClientSettings",
            provider=cfn.CustomResourceProvider.lambda_(
                lambda_.SingletonFunction(
                    self, "CognitoUserPoolClientClientSettingsLambda",
                    uuid="f7d4f730-4ee1-11e8-9c2d-fa7ae01bbebc",
                    code=lambda_.InlineCode(code_body),
                    handler="index.handler",
                    runtime=lambda_.Runtime.NODEJS_8_10,
                    role=iam.Role.from_role_arn(
                        self, 'CustomResourceRoleiam', role_arn=CustomResourceRole.attr_arn)
                )
            ),
            properties={"UserPoolId": CognitoUserPool.ref,
                        "UserPoolClientId": CognitoUserPoolClient.ref,
                        "AppDomain": AppDomain.value_as_string,
                        "SupportedIdentityProviders": ['COGNITO'],
                        "CallbackURL": CallbackURL.value_as_string,
                        "LogoutURL": LogoutURL.value_as_string,
                        "AllowedOAuthFlowsUserPoolClient": True,
                        "AllowedOAuthFlows": ['code'],
                        "AllowedOAuthScopes": ['openid']
                        },
        )

        # CognitoIdPool
        CognitoIdPool = cognito.CfnIdentityPool(
            self, 'CognitoIdPool',
            identity_pool_name='edxcognitoidpool',
            cognito_identity_providers=[{
                "clientId": CognitoUserPoolClient.ref,
                "providerName": CognitoUserPool.attr_provider_name
            }],
            allow_unauthenticated_identities=False
        )

        # Output
        core.CfnOutput(self, "CognitoUserPoolIdOutput",
                       value=CognitoUserPool.ref,
                       description="The Pool ID of the Cognito User Pool",
                       export_name="CognitoUserPoolId"
                       )
        core.CfnOutput(self, "CognitoUserPoolProviderURLOutput",
                       value=CognitoUserPool.attr_provider_url,
                       description="The Pool ProviderURL of the Cognito User Pool",
                       export_name="CognitoUserPoolProviderURL"
                       )
        core.CfnOutput(self, "CognitoUserPoolArnOutput",
                       value=CognitoUserPool.attr_arn,
                       description="The Pool Arn of the Cognito User Pool",
                       export_name="CognitoUserPoolArn"
                       )
        core.CfnOutput(self, "CognitoUserPoolClientIdOutput",
                       value=CognitoUserPoolClient.ref,
                       description="The App Client ID ",
                       export_name="CognitoUserPoolClientId"
                       )
        core.CfnOutput(self, "ClientSecretOutput",
                       value=core.Fn.get_att(
                           "CognitoUserPoolClientClientSettings", "ClientSecret").to_string(),
                       description="The Client Secret ",
                       export_name="ClientSecret"
                       )
Example #8
0
    def __init__(self, scope: core.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        prj_name = self.node.try_get_context('project_name')
        env_name = self.node.try_get_context('env')

        user_pool2 = cognito.UserPool(
            self,
            id=f'{env_name}-precog',
            auto_verify=cognito.AutoVerifiedAttrs(email=True),
            sign_in_aliases=cognito.SignInAliases(email=True, phone=True),
            self_sign_up_enabled=True,
            user_pool_name=f'{env_name}-cdk-2-user-pool',
            custom_attributes={
                "param1": cognito.StringAttribute(mutable=True)
            },
            password_policy=cognito.PasswordPolicy(min_length=10,
                                                   require_lowercase=True,
                                                   require_digits=True,
                                                   require_symbols=False,
                                                   require_uppercase=True))

        user_pool = cognito.CfnUserPool(
            self,
            id=f'{env_name}-cognito-user-pool',
            auto_verified_attributes=['email'],
            username_attributes=['email', 'phone_number'],
            user_pool_name=f'{env_name}-cdk-user-pool',
            schema=[{
                "attributeDataType": "String",
                "name": "param1",
                "mutable": True
            }],
            policies=cognito.CfnUserPool.PoliciesProperty(
                password_policy=cognito.CfnUserPool.PasswordPolicyProperty(
                    minimum_length=10,
                    require_lowercase=True,
                    require_numbers=True,
                    require_symbols=False,
                    require_uppercase=True)))

        user_pool_client2 = cognito.UserPoolClient(
            self,
            id=f'{env_name}-pool-client2',
            user_pool=user_pool2,
            user_pool_client_name=f'{env_name}-cdk-app-client2')
        identity_pool2 = cognito.CfnIdentityPool(
            self,
            id=f'{env_name}-identify-pool-2',
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[
                cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
                    client_id=user_pool_client2.user_pool_client_id,
                    provider_name=user_pool.attr_provider_name)
            ],
            identity_pool_name=f'{env_name}-cdk-identity-pool2')

        user_pool_client = cognito.CfnUserPoolClient(
            self,
            id=f'{env_name}-pool-client',
            user_pool_id=user_pool.ref,
            client_name=f'{env_name}-cdk-app-client')

        identity_pool = cognito.CfnIdentityPool(
            self,
            id=f'{env_name}-identify-pool',
            allow_unauthenticated_identities=False,
            cognito_identity_providers=[
                cognito.CfnIdentityPool.CognitoIdentityProviderProperty(
                    client_id=user_pool_client.ref,
                    provider_name=user_pool.attr_provider_name)
            ],
            identity_pool_name=f'{env_name}-cdk-identity-pool')

        ssm.StringParameter(
            self,
            id='app-id',
            parameter_name=f"/{env_name}/cognito-app-client-id",
            string_value=user_pool_client.ref)

        ssm.StringParameter(self,
                            id='user-pool-id',
                            parameter_name=f"/{env_name}/cognito-user-pool-id",
                            string_value=user_pool_client.user_pool_id)

        ssm.StringParameter(
            self,
            id='identity-pool-id',
            parameter_name=f"/{env_name}/cognito-identity-pool-id",
            string_value=identity_pool.ref  # ref returns the id
        )
Example #9
0
    def __init__(self, scope: core.App, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # create Cognito user pool
        user_pool = cognito.UserPool(
            self,
            "testUserPool",
            auto_verified_attributes=[cognito.UserPoolAttribute.EMAIL],
            sign_in_type=cognito.SignInType.EMAIL)
        cfn_user_pool = user_pool.node.default_child
        cfn_user_pool.policies = {
            "passwordPolicy": {
                "minimumLength": 8,
                "requireLowercase": True,
                "requireNumbers": True,
                "requireUppercase": True,
                "requireSymbols": False
            }
        }

        # attach a domain
        # random.seed(20191113)
        # random_domain = ''.join(random.choice(string.ascii_lowercase) for i in range(20))
        # cfn_user_pool_domain = cognito.CfnUserPoolDomain(
        #     self, "testUserPoolDomain",
        #     domain=random_domain,
        #     user_pool_id=user_pool.user_pool_id
        # )

        # create pool client
        pool_client = cognito.CfnUserPoolClient(
            self,
            'testUserPoolClient',
            user_pool_id=user_pool.user_pool_id,
            supported_identity_providers=["COGNITO"],
            generate_secret=False,
            refresh_token_validity=1,
            explicit_auth_flows=["USER_PASSWORD_AUTH"],
            allowed_o_auth_flows_user_pool_client=True,
            allowed_o_auth_flows=["implicit"],
            allowed_o_auth_scopes=[
                "email", "openid", "aws.cognito.signin.user.admin"
            ],
            callback_ur_ls=["http://localhost"],
            logout_ur_ls=["http://localhost"])
        # output some stuff
        core.CfnOutput(self, "User Pool ID", value=user_pool.user_pool_id)
        core.CfnOutput(self, "Pool Client ID", value=pool_client.ref)
        # core.CfnOutput(self, "User pool domain", value=cfn_user_pool_domain.domain)

        # create REST API resource
        api = apigw.RestApi(self, 'my_API')

        # new resource - /test
        test_resource = api.root.add_resource('test')

        # Cognito authorizer
        cfn_authorizer = apigw.CfnAuthorizer(
            self,
            "my_cognito",
            name='API_authorizer',
            type='COGNITO_USER_POOLS',
            identity_source='method.request.header.Authorization',
            rest_api_id=api.rest_api_id,
            provider_arns=[user_pool.user_pool_arn])

        # lambda handler
        hello_world_handler = _lambda.Function(
            self,
            'my_handler',
            code=_lambda.AssetCode('lambda'),
            handler='index.handler',
            runtime=_lambda.Runtime.PYTHON_3_7)

        # attach GET method
        hello_world_integration = apigw.LambdaIntegration(hello_world_handler)
        meth = test_resource.add_method(
            "GET",
            hello_world_integration,
            authorization_type=apigw.AuthorizationType.COGNITO)
        meth.node.find_child('Resource').add_property_override(
            'AuthorizerId', cfn_authorizer.ref)