AWSTemplateFormatVersion: 2010-09-09
Description: Data Feeds Delivery Resources
Parameters:
  S3BucketName:
    Description: "Bucket Name"
    Type: String
  SnsTopicName:
    Description: "The name of the topic where the notification will be sent when there's new data"
    Type: String

Conditions:
  HasSNSTopicName:
    Fn::Not:
      - Fn::Equals: ["", Ref: SnsTopicName]

Mappings:
  Configuration:
    ServicePrincipal:
      Value: "reports.marketplace.amazonaws.com"

Resources:
  KMSKey:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Version: "2012-10-17"
        Id: KMSKeyPolicy
        Statement:
          - Sid: Owner Access
            Effect: Allow
            Action:
              - kms:*
            Principal:
              AWS:
                - Fn::Sub: arn:aws:iam::${AWS::AccountId}:root
            Resource: "*"
          - Sid: Aws Marketplace Data Feeds Access
            Effect: Allow
            Action:
              - "kms:Encrypt"
              - "kms:Decrypt"
              - "kms:DescribeKey"
              - "kms:GenerateDataKey"
            Principal:
              Service: !FindInMap [Configuration, ServicePrincipal, Value]
            Resource: "*"
            Condition:
              StringLike:
                "kms:EncryptionContext:aws:s3:arn":
                  Fn::Sub: "arn:aws:s3:::${S3BucketName}/*"

  KMSKeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName:
        Fn::Sub: "alias/AWSMarketplaceDataFeeds-${S3BucketName}"
      TargetKeyId: !Ref 'KMSKey'

  S3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Ref 'S3BucketName'
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: aws:kms
              KMSMasterKeyID:
                Fn::GetAtt:
                  - KMSKey
                  - Arn

  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket:
        Ref: S3Bucket
      PolicyDocument:
        Statement:
          - Sid: AwsMarketplaceDataFeedsAccess
            Effect: Allow
            Action:
              - "s3:ListBucket"
              - "s3:GetObject"
              - "s3:PutObject"
              - "s3:GetEncryptionConfiguration"
              - "s3:GetBucketAcl"
              - "s3:PutObjectAcl"
            Resource:
              - Fn::Sub: arn:aws:s3:::${S3Bucket}
              - Fn::Sub: arn:aws:s3:::${S3Bucket}/*
            Principal:
              Service: !FindInMap [Configuration, ServicePrincipal, Value]
          - Sid: DenyIncorrectEncryptionHeader
            Effect: Deny
            Principal: "*"
            Action: s3:PutObject
            Resource:
              Fn::Sub: arn:aws:s3:::${S3Bucket}/*
            Condition:
              StringNotEquals:
                s3:x-amz-server-side-encryption: aws:kms
          - Sid: DenyUnencryptedObjectUploads
            Effect: Deny
            Principal: "*"
            Action: s3:PutObject
            Resource:
              Fn::Sub: arn:aws:s3:::${S3Bucket}/*
            Condition:
              Bool:
                s3:x-amz-server-side-encryption: true

  SNSTopic:
    Type: 'AWS::SNS::Topic'
    Condition: HasSNSTopicName
    Properties:
      TopicName: !Ref SnsTopicName

  EventTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Condition: HasSNSTopicName
    Properties:
      PolicyDocument:
        Statement:
          - Sid: AwsMarketplaceDataFeedsAccess
            Effect: Allow
            Principal:
              Service: !FindInMap [Configuration, ServicePrincipal, Value]
            Action: 'sns:Publish'
            Resource: !Ref SNSTopic
      Topics:
        - !Ref SNSTopic

Outputs:
  SnsTopicArn:
    Description: "SNS Topic Arn"
    Condition: HasSNSTopicName
    Value: !Ref SNSTopic
  S3BucketArn:
    Description: "S3 Bucket Arn"
    Value: !GetAtt S3Bucket.Arn
  KmsKeyArn:
    Description: "KMS Key Arn"
    Value: !GetAtt KMSKey.Arn
