AWSTemplateFormatVersion: 2010-09-09

Parameters:
  env:
    Type: String
  authRoleArn:
    Type: String
  unauthRoleArn:
    Type: String

  

    
  identityPoolName:
    Type: String
  
            
  
  allowUnauthenticatedIdentities:
    Type: String
            
  resourceNameTruncated:
    Type: String
  
            
  userPoolName:
    Type: String
  
            
        
  autoVerifiedAttributes:
    Type: CommaDelimitedList
      
  mfaConfiguration:
    Type: String
  
            
        
  mfaTypes:
    Type: CommaDelimitedList
      
  smsAuthenticationMessage:
    Type: String
  
            
  smsVerificationMessage:
    Type: String
  
            
  emailVerificationSubject:
    Type: String
  
            
  emailVerificationMessage:
    Type: String
  
            
  
  defaultPasswordPolicy:
    Type: String
            
    
  passwordPolicyMinLength:
    Type: Number
          
        
  passwordPolicyCharacters:
    Type: CommaDelimitedList
      
        
  requiredAttributes:
    Type: CommaDelimitedList
      
  
  userpoolClientGenerateSecret:
    Type: String
            
    
  userpoolClientRefreshTokenValidity:
    Type: Number
          
        
  userpoolClientWriteAttributes:
    Type: CommaDelimitedList
      
        
  userpoolClientReadAttributes:
    Type: CommaDelimitedList
      
  userpoolClientLambdaRole:
    Type: String
  
            
  
  userpoolClientSetAttributes:
    Type: String
            
  sharedId:
    Type: String
  
            
  resourceName:
    Type: String
  
            
  authSelections:
    Type: String
  
            
            
            
  useDefault:
    Type: String
  
            
        
  usernameAttributes:
    Type: CommaDelimitedList
      
  
  userPoolGroups:
    Type: String
            
  
  adminQueries:
    Type: String
            
  triggers:
    Type: String
  
            
  
  hostedUI:
    Type: String
            
        
  userPoolGroupList:
    Type: CommaDelimitedList
      
  serviceName:
    Type: String
  
            
  
  usernameCaseSensitive:
    Type: String
            
      
  parentStack:
    Type: String
        
        
  permissions:
    Type: CommaDelimitedList
      
        
  dependsOn:
    Type: CommaDelimitedList
      
            
Conditions:
  ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]

Resources:
  
  
  # BEGIN SNS ROLE RESOURCE
  SNSRole:
  # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
    Type: AWS::IAM::Role
    Properties:
      RoleName: !If [ShouldNotCreateEnvResources, 'listif0c093a99_sns-role', !Join ['',[ 'sns', '0c093a99', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: ""
            Effect: "Allow"
            Principal:
              Service: "cognito-idp.amazonaws.com"
            Action:
              - "sts:AssumeRole"
            Condition:
              StringEquals:
                sts:ExternalId: listif0c093a99_role_external_id
      Policies:
        -
          PolicyName: listif0c093a99-sns-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action:
                  - "sns:Publish"
                Resource: "*"
  # BEGIN USER POOL RESOURCES
  UserPool:
  # Created upon user selection
  # Depends on SNS Role for Arn if MFA is enabled
    Type: AWS::Cognito::UserPool
    UpdateReplacePolicy: Retain
    Properties:
      UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
      
      
      UsernameConfiguration:
        CaseSensitive: false
      
      Schema:
        
        -
          Name: email
          Required: true
          Mutable: true
        
      
      
      
      AutoVerifiedAttributes: !Ref autoVerifiedAttributes
      
      
      EmailVerificationMessage: !Ref emailVerificationMessage
      EmailVerificationSubject: !Ref emailVerificationSubject
      
      Policies:
        PasswordPolicy:
          MinimumLength: !Ref passwordPolicyMinLength
          RequireLowercase: false
          RequireNumbers: false
          RequireSymbols: false
          RequireUppercase: false
      
      UsernameAttributes: !Ref usernameAttributes
      
      MfaConfiguration: !Ref mfaConfiguration
      SmsVerificationMessage: !Ref smsVerificationMessage
      SmsConfiguration:
        SnsCallerArn: !GetAtt SNSRole.Arn
        ExternalId: listif0c093a99_role_external_id
    
  
  
  
  
  
  
  
  
  
  
  # Updating lambda role with permissions to Cognito
  
  
  UserPoolClientWeb:
  # Created provide application access to user pool
  # Depends on UserPool for ID reference
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      ClientName: listif0c093a99_app_clientWeb
      
      RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
      UserPoolId: !Ref UserPool
    DependsOn: UserPool
  UserPoolClient:
  # Created provide application access to user pool
  # Depends on UserPool for ID reference
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      ClientName: listif0c093a99_app_client
      
      GenerateSecret: !Ref userpoolClientGenerateSecret
      RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
      UserPoolId: !Ref UserPool
    DependsOn: UserPool
  # BEGIN USER POOL LAMBDA RESOURCES
  UserPoolClientRole:
  # Created to execute Lambda which gets userpool app client config values
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', '0c093a99', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
    DependsOn: UserPoolClient
  UserPoolClientLambda:
  # Lambda which gets userpool app client config values
  # Depends on UserPool for id
  # Depends on UserPoolClientRole for role ARN
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        ZipFile: !Join
          - |+
          - - 'const response = require(''cfn-response'');'
            - 'const aws = require(''aws-sdk'');'
            - 'const identity = new aws.CognitoIdentityServiceProvider();'
            - 'exports.handler = (event, context, callback) => {'
            - ' if (event.RequestType == ''Delete'') { '
            - '   response.send(event, context, response.SUCCESS, {})'
            - ' }'
            - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
            - '   const params = {'
            - '     ClientId: event.ResourceProperties.clientId,'
            - '     UserPoolId: event.ResourceProperties.userpoolId'
            - '   };'
            - '   identity.describeUserPoolClient(params).promise()'
            - '     .then((res) => {'
            - '       response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
            - '     })'
            - '     .catch((err) => {'
            - '       response.send(event, context, response.FAILED, {err});'
            - '     });'
            - ' }'
            - '};'
      Handler: index.handler
      Runtime: nodejs10.x
      Timeout: '300'
      Role: !GetAtt
        - UserPoolClientRole
        - Arn
    DependsOn: UserPoolClientRole
  UserPoolClientLambdaPolicy:
  # Sets userpool policy for the role that executes the Userpool Client Lambda
  # Depends on UserPool for Arn
  # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
    Type: 'AWS::IAM::Policy'
    Properties:
      PolicyName: listif0c093a99_userpoolclient_lambda_iam_policy
      Roles:
        - !Ref UserPoolClientRole
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - 'cognito-idp:DescribeUserPoolClient'
            Resource: !GetAtt UserPool.Arn
    DependsOn: UserPoolClientLambda
  UserPoolClientLogPolicy:
  # Sets log policy for the role that executes the Userpool Client Lambda
  # Depends on UserPool for Arn
  # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
    Type: 'AWS::IAM::Policy'
    Properties:
      PolicyName: listif0c093a99_userpoolclient_lambda_log_policy
      Roles:
        - !Ref UserPoolClientRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - 'logs:CreateLogGroup'
              - 'logs:CreateLogStream'
              - 'logs:PutLogEvents'
            Resource: !Sub
              - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
              - { region: !Ref "AWS::Region",  account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
    DependsOn: UserPoolClientLambdaPolicy
  UserPoolClientInputs:
  # Values passed to Userpool client Lambda
  # Depends on UserPool for Id
  # Depends on UserPoolClient for Id
  # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
    Type: 'Custom::LambdaCallout'
    Properties:
      ServiceToken: !GetAtt UserPoolClientLambda.Arn
      clientId: !Ref UserPoolClient
      userpoolId: !Ref UserPool
    DependsOn: UserPoolClientLogPolicy
  

  
  

  
    
  # BEGIN IDENTITY POOL RESOURCES
  

  IdentityPool:
  # Always created
    Type: AWS::Cognito::IdentityPool
    Properties:
      IdentityPoolName: !If [ShouldNotCreateEnvResources, 'listify0c093a990c093a99_identitypool_6bcaf6ac', !Join ['',['listify0c093a990c093a99_identitypool_6bcaf6ac', '__', !Ref env]]]
      
      CognitoIdentityProviders:
        - ClientId:  !Ref UserPoolClient
          ProviderName: !Sub
            - cognito-idp.${region}.amazonaws.com/${client}
            - { region: !Ref "AWS::Region",  client: !Ref UserPool}
        - ClientId:  !Ref UserPoolClientWeb
          ProviderName: !Sub
            - cognito-idp.${region}.amazonaws.com/${client}
            - { region: !Ref "AWS::Region",  client: !Ref UserPool}
            
      AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
      
    
    DependsOn: UserPoolClientInputs
    

  IdentityPoolRoleMap:
  # Created to map Auth and Unauth roles to the identity pool
  # Depends on Identity Pool for ID ref
    Type: AWS::Cognito::IdentityPoolRoleAttachment
    Properties:
      IdentityPoolId: !Ref IdentityPool
      Roles:
          unauthenticated: !Ref unauthRoleArn
          authenticated: !Ref authRoleArn
    DependsOn: IdentityPool
  

Outputs :
  
  IdentityPoolId:
    Value: !Ref 'IdentityPool'
    Description:  Id for the identity pool
  IdentityPoolName:
    Value: !GetAtt IdentityPool.Name
  
  
  
  
  UserPoolId:
    Value: !Ref 'UserPool'
    Description:  Id for the user pool
  UserPoolName:
    Value: !Ref userPoolName
  AppClientIDWeb:
    Value: !Ref 'UserPoolClientWeb'
    Description: The user pool app client id for web
  AppClientID:
    Value: !Ref 'UserPoolClient'
    Description: The user pool app client id
  AppClientSecret:
    Value: !GetAtt UserPoolClientInputs.appSecret
  
  
  
  
  
  
  
