AWSTemplateFormatVersion: '2010-09-09'
Description: 'DVSA: a Damn Vulnerable Serverless Application.'
Outputs:
  WebsiteURL:
    Description: DVSA Website URL
    Value:
      Fn::Join:
      - ''
      - - http://dvsa-website-
        - Ref: AWS::AccountId
        - .s3-website-
        - Ref: AWS::Region
        - .amazonaws.com
Parameters:
  targetStage:
    Default: dev
    Description: Define stage to which Lambdas/API Gateways should be deployed.
    Type: String
Resources:
  AdminGetOrders:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 0417291a-1c9b-401f-9535-9be4fab6214a
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ADMIN-GET-ORDERS
      Handler: admin-get-orders.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaAdminRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  AdminGetReceipt:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 0417291a-1c9b-401f-9535-9be4fab6214a
      Description: ''
      Environment:
        Variables:
          RECEIPTS_BUCKET:
            Fn::Join:
            - ''
            - - dvsa-receipts-bucket-
              - Ref: AWS::AccountId
      FunctionName: DVSA-ADMIN-GET-RECEIPT
      Handler: admin-get-receipts.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaAdminRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  AdminTweet:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 0417291a-1c9b-401f-9535-9be4fab6214a
      Description: ''
      Environment:
        Variables:
          TWITTER_ACCESS_TOKEN: grGmA8YH4KID2JquF10n6GFEG
          TWITTER_API: https://api.twitter.com/
          TWITTER_TOKEN_SECRET: zOZ5pc8ndrSZGwetFnBUGCr5O8kF69vEU6p1FiYOFpfJuWBjlm
      FunctionName: DVSA-ADMIN-TWEET
      Handler: admin-tweet.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaAdminRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  AdminUpdateInventory:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 0417291a-1c9b-401f-9535-9be4fab6214a
      Description: ''
      Environment:
        Variables:
          INVENTORY_TABLE: DVSA-INVENTORY-DB
      FunctionName: DVSA-ADMIN-UPDATE-INVENTORY
      Handler: admin-update-inventory.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaAdminRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  AdminUpdateOrders:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 0417291a-1c9b-401f-9535-9be4fab6214a
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ADMIN-UPDATE-ORDERS
      Handler: admin-update-orders.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaAdminRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  ApiGatewayApi:
    Properties:
      Cors:
        AllowHeaders: '''*'''
        AllowMethods: '''*'''
        AllowOrigin: '''*'''
      DefinitionBody:
        basePath: /
        definitions:
          Empty:
            title: Empty Schema
            type: object
        info:
          title: AwsServerlessOptionsApi
        paths:
          /order:
            options:
              consumes:
              - application/json
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  headers:
                    Access-Control-Allow-Headers:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Origin:
                      type: string
                  schema:
                    $ref: '#/definitions/Empty'
              tags:
              - CORS
              x-amazon-apigateway-integration:
                passthroughBehavior: when_no_match
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                responses:
                  default:
                    responseParameters:
                      method.response.header.Access-Control-Allow-Headers: '''Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'''
                      method.response.header.Access-Control-Allow-Methods: '''OPTIONS,POST'''
                      method.response.header.Access-Control-Allow-Origin: '''*'''
                    statusCode: 200
                type: mock
            post:
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  schema:
                    $ref: '#/definitions/Empty'
              x-amazon-apigateway-integration:
                httpMethod: POST
                passthroughBehavior: when_no_match
                responses:
                  default:
                    statusCode: 200
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${OrderManagerJsFunction.Arn}/invocations
          /payment:
            options:
              consumes:
              - application/json
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  headers:
                    Access-Control-Allow-Headers:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Origin:
                      type: string
                  schema:
                    $ref: '#/definitions/Empty'
              tags:
              - CORS
              x-amazon-apigateway-integration:
                passthroughBehavior: when_no_match
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                responses:
                  default:
                    responseParameters:
                      method.response.header.Access-Control-Allow-Headers: '''Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'''
                      method.response.header.Access-Control-Allow-Methods: '''OPTIONS,POST'''
                      method.response.header.Access-Control-Allow-Origin: '''*'''
                    statusCode: 200
                type: mock
            post:
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  schema:
                    $ref: '#/definitions/Empty'
              x-amazon-apigateway-integration:
                httpMethod: POST
                passthroughBehavior: when_no_match
                responses:
                  default:
                    statusCode: 200
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PaymentProcessorFunction.Arn}/invocations
          /total:
            options:
              consumes:
              - application/json
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  headers:
                    Access-Control-Allow-Headers:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Origin:
                      type: string
                  schema:
                    $ref: '#/definitions/Empty'
              tags:
              - CORS
              x-amazon-apigateway-integration:
                passthroughBehavior: when_no_match
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                responses:
                  default:
                    responseParameters:
                      method.response.header.Access-Control-Allow-Headers: '''Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'''
                      method.response.header.Access-Control-Allow-Methods: '''OPTIONS,POST'''
                      method.response.header.Access-Control-Allow-Origin: '''*'''
                    statusCode: 200
                type: mock
            post:
              produces:
              - application/json
              responses:
                '200':
                  description: 200 response
                  schema:
                    $ref: '#/definitions/Empty'
              x-amazon-apigateway-integration:
                httpMethod: POST
                passthroughBehavior: when_no_match
                responses:
                  default:
                    statusCode: 200
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTotalFunction.Arn}/invocations
        schemes:
        - http
        swagger: 2.0
      StageName:
        Fn::Sub: ${targetStage}
    Type: AWS::Serverless::Api
  ApiGatewayAuthorizer:
    Properties:
      AuthorizerResultTtlInSeconds: 300
      IdentitySource: method.request.header.Authorization
      Name:
        Fn::Sub: ${targetStage}DVSACognitoAuthorizer
      ProviderARNs:
      - Fn::GetAtt:
        - CognitoUserPoolMyUserPool
        - Arn
      RestApiId:
        Ref: ApiGatewayApi
      Type: COGNITO_USER_POOLS
    Type: AWS::ApiGateway::Authorizer
  ClientBucket:
    DeletionPolicy: Retain
    Properties:
      BucketName:
        Fn::Join:
        - ''
        - - dvsa-website-
          - Ref: AWS::AccountId
      CorsConfiguration:
        CorsRules:
        - AllowedHeaders:
          - '*'
          AllowedMethods:
          - GET
          - PUT
          - POST
          - DELETE
          - HEAD
          AllowedOrigins:
          - '*'
          MaxAge: 3000
      WebsiteConfiguration:
        ErrorDocument: index.html
        IndexDocument: index.html
    Type: AWS::S3::Bucket
  CognitoAuthRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRoleWithWebIdentity
          Condition:
            ForAnyValue:StringLike:
              cognito-identity.amazonaws.com:amr: authenticated
            StringEquals:
              cognito-identity.amazonaws.com:aud:
                Ref: CognitoIdentityPool
          Effect: Allow
          Principal:
            Federated: cognito-identity.amazonaws.com
        Version: '2012-10-17'
      Path: /
    Type: AWS::IAM::Role
  CognitoIdentityPool:
    Properties:
      AllowUnauthenticatedIdentities: false
      CognitoIdentityProviders:
      - ClientId:
          Ref: CognitoUserPoolClient
        ProviderName:
          Fn::GetAtt:
          - CognitoUserPoolMyUserPool
          - ProviderName
      IdentityPoolName:
        Fn::Sub: ${targetStage}DVSAIdentityPool
    Type: AWS::Cognito::IdentityPool
  CognitoIdentityPoolRoles:
    Properties:
      IdentityPoolId:
        Ref: CognitoIdentityPool
      Roles:
        authenticated:
          Fn::GetAtt:
          - CognitoAuthRole
          - Arn
    Type: AWS::Cognito::IdentityPoolRoleAttachment
  CognitoUserPoolClient:
    Properties:
      ClientName:
        Fn::Sub: ${targetStage}-user-pool-client
      ExplicitAuthFlows:
      - ADMIN_NO_SRP_AUTH
      GenerateSecret: false
      UserPoolId:
        Ref: CognitoUserPoolMyUserPool
    Type: AWS::Cognito::UserPoolClient
  CognitoUserPoolMyUserPool:
    Properties:
      AutoVerifiedAttributes:
      - email
      LambdaConfig:
        PostConfirmation:
          Fn::GetAtt:
          - UserCreate
          - Arn
      Policies:
        PasswordPolicy:
          MinimumLength: 6
          RequireLowercase: false
          RequireNumbers: false
          RequireSymbols: false
          RequireUppercase: false
      UserPoolName:
        Fn::Sub: ${targetStage}-user-pool
      UsernameAttributes:
      - email
    Type: AWS::Cognito::UserPool
  CreateReceiptFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 4a2c467a-aad1-48d0-93be-9108b0ee8251
      Description: ''
      Environment:
        Variables:
          INVENTORY_TABLE: DVSA-INVENTORY-DB
          ORDERS_TABLE: DVSA-ORDERS-DB
          RECEIPTS_BUCKET:
            Fn::Join:
            - ''
            - - dvsa-receipts-bucket-
              - Ref: AWS::AccountId
      Events:
        MySQSEvent:
          Properties:
            BatchSize: 1
            Queue:
              Fn::GetAtt:
              - SQSQueue
              - Arn
          Type: SQS
      FunctionName: DVSA-CREATE-RECEIPT
      Handler: create-receipt.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-INVENTORY-DB
          Effect: Allow
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      - Statement:
        - Action:
          - s3:GetObject
          - s3:ListBucket
          - s3:GetBucketLocation
          - s3:GetObjectVersion
          - s3:PutObject
          - s3:GetLifecycleConfiguration
          - s3:PutLifecycleConfiguration
          - s3:DeleteObject
          Resource:
          - Fn::Sub:
            - arn:${AWS::Partition}:s3:::${bucketName}
            - bucketName:
                Fn::Join:
                - ''
                - - dvsa-receipts-bucket-
                  - Ref: AWS::AccountId
          - Fn::Sub:
            - arn:${AWS::Partition}:s3:::${bucketName}/*
            - bucketName:
                Fn::Join:
                - ''
                - - dvsa-receipts-bucket-
                  - Ref: AWS::AccountId
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  CronJobUpdate:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 73c6cef6-8060-4eb0-b1f6-0be662122c52
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      Events:
        Timer:
          Properties:
            Schedule: rate(1 day)
          Type: Schedule
      FunctionName: DVSA-CRON-JOB-UPDATE
      Handler: cron-update.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaCronjobsRole
        - Arn
      Runtime: python2.7
      Timeout: 30
    Type: AWS::Serverless::Function
  CronOrderCleaner:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 73c6cef6-8060-4eb0-b1f6-0be662122c52
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      Events:
        Timer:
          Properties:
            Schedule: rate(1 day)
          Type: Schedule
      FunctionName: DVSA-CRON-ORDER-CLEANER
      Handler: cron-cleaner.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaCronjobsRole
        - Arn
      Runtime: python2.7
      Timeout: 30
    Type: AWS::Serverless::Function
  CronProcessor:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 73c6cef6-8060-4eb0-b1f6-0be662122c52
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      Events:
        Timer:
          Properties:
            Schedule: rate(1 day)
          Type: Schedule
      FunctionName: DVSA-CRON-PROCESSOR
      Handler: cron-processor.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaCronjobsRole
        - Arn
      Runtime: python2.7
      Timeout: 30
    Type: AWS::Serverless::Function
  DVSAWebsiteUrl:
    Properties:
      Description: DVSA Website URL after Deployment
      Name: DVSA-Website-URL
      Type: String
      Value:
        Fn::Join:
        - ''
        - - http://dvsa-website-
          - Ref: AWS::AccountId
          - .s3-website-
          - Ref: AWS::Region
          - .amazonaws.com
    Type: AWS::SSM::Parameter
  GetTotalFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 4a2c467a-aad1-48d0-93be-9108b0ee8251
      Description: ''
      Environment:
        Variables:
          INVENTORY_TABLE: DVSA-INVENTORY-DB
      Events:
        CartTotalApi:
          Properties:
            Method: POST
            Path: /total
            RestApiId:
              Ref: ApiGatewayApi
          Type: Api
      FunctionName: DVSA-GET-CART-TOTAL
      Handler: get-cart-total.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-INVENTORY-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  InitFunctionLambda:
    DeletionPolicy: Retain
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 455bf337-f4ff-44fd-8444-abbed7697bdb
      Description: ''
      Environment:
        Variables:
          CLIENT_BUCKET:
            Fn::Join:
            - ''
            - - dvsa-website-
              - Ref: AWS::AccountId
          IDENTITY_POOL:
            Ref: CognitoIdentityPool
          ORDER_API:
            Fn::Sub: https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/${targetStage}
          RECEIPTS_BUCKET:
            Fn::Join:
            - ''
            - - dvsa-receipts-bucket-
              - Ref: AWS::AccountId
          USER_POOL_CLIENT_ID:
            Ref: CognitoUserPoolClient
          USER_POOL_ID:
            Ref: CognitoUserPoolMyUserPool
      FunctionName: DVSA-INIT
      Handler: dvsa-init.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - InitFunctionRole
        - Arn
      Runtime: python2.7
      Timeout: 120
    Type: AWS::Serverless::Function
  InitFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            - logs:DeleteLogGroup
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:logs
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - log-group:/aws/lambda/*:*:*
          - Action:
            - dynamodb:*
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:dynamodb
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - table/*
          - Action:
            - s3:*
            Effect: Allow
            Resource:
              Fn::Join:
              - ''
              - - arn:aws:s3:::dvsa-website-
                - Ref: AWS::AccountId
          - Action:
            - ses:VerifyEmailIdentity
            - ses:DeleteIdentity
            - ses:DeleteVerifiedEmailAddress
            - ses:ListIdentities
            - ses:VerifyEmailAddress
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: ${targetStage}InitFunctionRolePolicy
      RoleName:
        Fn::Sub: ${targetStage}InitFunctionRole
    Type: AWS::IAM::Role
  InitializeApplication:
    Properties:
      ServiceToken:
        Fn::GetAtt:
        - InitFunctionLambda
        - Arn
    Type: AWS::CloudFormation::CustomResource
  InventoryTable:
    Properties:
      AttributeDefinitions:
      - AttributeName: itemId
        AttributeType: S
      - AttributeName: category
        AttributeType: S
      KeySchema:
      - AttributeName: itemId
        KeyType: HASH
      - AttributeName: category
        KeyType: RANGE
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      TableName: DVSA-INVENTORY-DB
    Type: AWS::DynamoDB::Table
  LambdaCognitoUserPoolExecutionPermission:
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Fn::GetAtt:
        - UserCreate
        - Arn
      Principal: cognito-idp.amazonaws.com
      SourceArn:
        Fn::Sub: arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${CognitoUserPoolMyUserPool}
    Type: AWS::Lambda::Permission
  OrderBillingFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          GET_CART_TOTAL:
            Fn::Sub: https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/${targetStage}/total
          ORDERS_TABLE: DVSA-ORDERS-DB
          PAYMENT_PROCESS_URL:
            Fn::Sub: https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/${targetStage}/payment
          SQS_URL:
            Fn::Sub: https://sqs.${AWS::Region}.amazonaws.com/${AWS::AccountId}/dvsa-order-paid-sqs
      FunctionName: DVSA-ORDER-BILLING
      Handler: order-billing.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      - Statement:
        - Action:
          - sqs:SendMessage*
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}
            - queueName: dvsa-order-paid-sqs
          Effect: Allow
      Runtime: python2.7
      Timeout: 30
    Type: AWS::Serverless::Function
  OrderCancelFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-CANCEL
      Handler: cancel-order.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrderGetFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-GET
      Handler: get-order.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrderManagerJsFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 52bacc36-822b-49b2-951d-b3f56d642f5a
      Description: ''
      Events:
        OrderApi:
          Properties:
            Method: POST
            Path: /order
            RestApiId:
              Ref: ApiGatewayApi
          Type: Api
      FunctionName: DVSA-ORDER-MANAGER-JS
      Handler: order-manager-js.handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - lambda:InvokeFunction
          - lambda:InvokeAsync
          Effect: Allow
          Resource:
            Fn::Join:
            - ':'
            - - arn:aws:lambda
              - Ref: AWS::Region
              - Ref: AWS::AccountId
              - function:*
        Version: '2012-10-17'
      Runtime: nodejs10.x
      Timeout: 30
    Type: AWS::Serverless::Function
  OrderNewFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-NEW
      Handler: new-order.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrderShippingFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-SHIPPING
      Handler: order-shipping.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrderUpdateFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-UPDATE
      Handler: update-order.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrdersGetFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: e073de99-1f79-4b27-a276-a0a0a8e8bf71
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
      FunctionName: DVSA-ORDER-ORDERS
      Handler: get-orders.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  OrdersTable:
    Properties:
      AttributeDefinitions:
      - AttributeName: orderId
        AttributeType: S
      - AttributeName: userId
        AttributeType: S
      KeySchema:
      - AttributeName: orderId
        KeyType: HASH
      - AttributeName: userId
        KeyType: RANGE
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      TableName: DVSA-ORDERS-DB
    Type: AWS::DynamoDB::Table
  PaymentProcessorFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 4a2c467a-aad1-48d0-93be-9108b0ee8251
      Description: ''
      Events:
        PaymentProcessorApi:
          Properties:
            Method: POST
            Path: /payment
            RestApiId:
              Ref: ApiGatewayApi
          Type: Api
      FunctionName: DVSA-PAYMENT-PROCESSOR
      Handler: payment-processing.lambda_handler
      MemorySize: 128
      Runtime: python2.7
      Timeout: 30
    Type: AWS::Serverless::Function
  ReceiptsBucket:
    Properties:
      BucketName:
        Fn::Join:
        - ''
        - - dvsa-receipts-bucket-
          - Ref: AWS::AccountId
      CorsConfiguration:
        CorsRules:
        - AllowedHeaders:
          - '*'
          AllowedMethods:
          - GET
          - PUT
          - POST
          - DELETE
          - HEAD
          AllowedOrigins:
          - '*'
          MaxAge: 3000
      NotificationConfiguration:
        LambdaConfigurations:
        - Function:
            Fn::GetAtt:
            - SendReceiptFunction
            - Arn
          Filter:
            S3Key:
              Rules:
              - Name: suffix
                Value: .raw
          Event: s3:ObjectCreated:*
    Type: AWS::S3::Bucket
    DependsOn:
    - SendReceiptFunctionReceiptUploadPermission
  S3BucketPermissions:
    Properties:
      Bucket:
        Fn::Join:
        - ''
        - - dvsa-receipts-bucket-
          - Ref: AWS::AccountId
      PolicyDocument:
        Statement:
        - Action:
          - s3:PutObject
          - s3:PutObjectAcl
          - s3:GetObject
          - s3:DeleteObject
          Effect: Allow
          Principal: '*'
          Resource:
            Fn::Join:
            - ''
            - - arn:aws:s3:::dvsa-receipts-bucket-
              - Ref: AWS::AccountId
              - /*
          Sid: PublicWriteReceiptsStatement
        - Action:
          - s3:*
          Effect: Allow
          Principal:
            AWS:
              Fn::GetAtt:
              - dvsaAdminRole
              - Arn
          Resource:
            Fn::Join:
            - ''
            - - arn:aws:s3:::dvsa-receipts-bucket-
              - Ref: AWS::AccountId
          Sid: AdminListReceiptsStatement
    Type: AWS::S3::BucketPolicy
  S3ClientBucketPermissions:
    Properties:
      Bucket:
        Fn::Join:
        - ''
        - - dvsa-website-
          - Ref: AWS::AccountId
      PolicyDocument:
        Statement:
        - Action:
          - s3:GetObject
          Effect: Allow
          Principal: '*'
          Resource:
            Fn::Join:
            - ''
            - - arn:aws:s3:::dvsa-website-
              - Ref: AWS::AccountId
              - /*
          Sid: PublicReadDistStatement
        - Action:
          - s3:*
          Effect: Allow
          Principal:
            AWS:
              Fn::GetAtt:
              - InitFunctionRole
              - Arn
          Resource:
            Fn::Join:
            - ''
            - - arn:aws:s3:::dvsa-website-
              - Ref: AWS::AccountId
          Sid: AdminClientStatement
        - Action:
          - s3:*
          Effect: Allow
          Principal:
            AWS:
              Fn::GetAtt:
              - InitFunctionRole
              - Arn
          Resource:
            Fn::Join:
            - ''
            - - arn:aws:s3:::dvsa-website-
              - Ref: AWS::AccountId
              - /*
          Sid: AdminClientWriteStatement
    Type: AWS::S3::BucketPolicy
  SQSQueue:
    Properties:
      QueueName: dvsa-order-paid-sqs
    Type: AWS::SQS::Queue
  SendReceiptFunction:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 4a2c467a-aad1-48d0-93be-9108b0ee8251
      Description: ''
      Environment:
        Variables:
          ORDERS_TABLE: DVSA-ORDERS-DB
          SOURCE_EMAIL: dvsa.noreply@mailsac.com
      Events:
        ReceiptUpload:
          Properties:
            Bucket:
              Ref: ReceiptsBucket
            Events: s3:ObjectCreated:*
            Filter:
              S3Key:
                Rules:
                - Name: suffix
                  Value: .raw
          Type: S3
      FunctionName: DVSA-SEND-RECEIPT-EMAIL
      Handler: send-receipt-email.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-ORDERS-DB
          Effect: Allow
      - Statement:
        - Action:
          - s3:GetObject
          - s3:ListBucket
          - s3:GetBucketLocation
          - s3:GetObjectVersion
          - s3:PutObject
          - s3:GetLifecycleConfiguration
          - s3:PutLifecycleConfiguration
          - s3:DeleteObject
          Resource:
          - Fn::Sub:
            - arn:${AWS::Partition}:s3:::${bucketName}
            - bucketName:
                Fn::Join:
                - ''
                - - dvsa-receipts-bucket-
                  - Ref: AWS::AccountId
          - Fn::Sub:
            - arn:${AWS::Partition}:s3:::${bucketName}/*
            - bucketName:
                Fn::Join:
                - ''
                - - dvsa-receipts-bucket-
                  - Ref: AWS::AccountId
          Effect: Allow
      - Statement:
        - Action:
          - sts:*
          - ses:*
          Effect: Allow
          Resource: '*'
        Version: '2012-10-17'
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  UserAccount:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 065c8722-2f4b-4fdb-ba5b-184e0985b8d8
      Description: ''
      Environment:
        Variables:
          USERS_TABLE: DVSA-USERS-DB
      FunctionName: DVSA-USER-ACCOUNT
      Handler: user-account.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-USERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  UserCreate:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 065c8722-2f4b-4fdb-ba5b-184e0985b8d8
      Description: ''
      Environment:
        Variables:
          GENERIC_AVATAR: https://i.imgur.com/tAmofRW.png
          USERS_TABLE: DVSA-USERS-DB
      FunctionName: DVSA-USER-CREATE
      Handler: user-create.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaCreateUserRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  UserInbox:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 065c8722-2f4b-4fdb-ba5b-184e0985b8d8
      Description: ''
      Environment:
        Variables:
          USERS_TABLE: DVSA-USERS-DB
      FunctionName: DVSA-USER-INBOX
      Handler: user-inbox.lambda_handler
      MemorySize: 128
      Role:
        Fn::GetAtt:
        - dvsaUserInboxRole
        - Arn
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  UserProfile:
    Properties:
      Tags:
        STAGE:
          Fn::Sub: ${targetStage}
      CodeUri:
        Bucket: <%REPO_BUCKET%>
        Key: 065c8722-2f4b-4fdb-ba5b-184e0985b8d8
      Description: ''
      Environment:
        Variables:
          USERS_TABLE: DVSA-USERS-DB
      FunctionName: DVSA-USER-PROFILE
      Handler: user-profile.lambda_handler
      MemorySize: 128
      Policies:
      - Statement:
        - Action:
          - dynamodb:GetItem
          - dynamodb:DeleteItem
          - dynamodb:PutItem
          - dynamodb:Scan
          - dynamodb:Query
          - dynamodb:UpdateItem
          - dynamodb:BatchWriteItem
          - dynamodb:BatchGetItem
          - dynamodb:DescribeTable
          Resource:
            Fn::Sub:
            - arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}
            - tableName: DVSA-USERS-DB
          Effect: Allow
      Runtime: python2.7
      Timeout: 10
    Type: AWS::Serverless::Function
  UsersTable:
    Properties:
      AttributeDefinitions:
      - AttributeName: userId
        AttributeType: S
      KeySchema:
      - AttributeName: userId
        KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      TableName: DVSA-USERS-DB
    Type: AWS::DynamoDB::Table
  dvsaAdminRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:logs
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - log-group:/aws/lambda/*:*:*
          - Action:
            - dynamodb:*
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:dynamodb
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - table/*
          - Action:
            - s3:*
            Effect: Allow
            Resource:
            - Fn::Join:
              - ''
              - - 'arn:aws:s3:::'
                - dvsa-receipts-bucket-
                - Ref: AWS::AccountId
                - /*
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: ${targetStage}dvsaAdminRolePolicy
      RoleName:
        Fn::Sub: ${targetStage}dvsaAdminRole
    Type: AWS::IAM::Role
  dvsaCreateUserRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:logs
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - log-group:/aws/lambda/*:*:*
          - Action:
            - dynamodb:*
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:dynamodb
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - table/*
          - Action:
            - lambda:InvokeFunction
            - lambda:InvokeAsync
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:lambda
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - function:*
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: ${targetStage}dvsaCreateUserRolePolicy
      RoleName:
        Fn::Sub: ${targetStage}dvsaCreateUserRole
    Type: AWS::IAM::Role
  dvsaCronjobsRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:logs
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - log-group:/aws/lambda/*:*:*
          - Action:
            - dynamodb:*
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:dynamodb
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - table/*
          - Action:
            - lambda:InvokeFunction
            - lambda:InvokeAsync
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:lambda
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - function:*
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: ${targetStage}dvsaCronjobsRolePolicy
      RoleName:
        Fn::Sub: ${targetStage}dvsaCronjobsRole
    Type: AWS::IAM::Role
  dvsaUserInboxRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Effect: Allow
            Resource:
              Fn::Join:
              - ':'
              - - arn:aws:logs
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - log-group:/aws/lambda/*:*:*
          - Action:
            - sts:*
            - ses:*
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName:
          Fn::Sub: ${targetStage}dvsaUserInboxRolePolicy
      RoleName:
        Fn::Sub: ${targetStage}dvsaUserInboxRole
    Type: AWS::IAM::Role
Transform: AWS::Serverless-2016-10-31