data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "power_user_mfa" {
  count = var.require_mfa ? 1 : 0

  statement {
    sid = "AllowEverythingExceptDestructActions"

    effect = "Allow"

    not_actions = sort([
      "iam:*",
      "organizations:*",
      "account:*",
      "kms:*",
      "rds:*",
      "sts:*",
      "guardduty:*",
      "cloudtrail:*",
      "secretsmanager:*",
      "route53:*",
      "ec2:Delete*",
      "ec2:Terminate*",
      "ecs:Delete*",
      "ecr:Delete*",
      "athena:Delete*",
      "elasticloadbalancing:Delete*",
      "acm:Delete*",
      "cloudfront:Delete*",
      "elasticache:Delete*",
      "s3:Create*",
      "ec2:CreateSecurityGroup",
    ])

    resources = [
      "*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }

  statement {
    sid = "AllowReadActions"

    effect = "Allow"

    actions = sort([
      "iam:ListRoles",
      "iam:PassRole",
      "iam:ListRolePolicies",
      "iam:ListAttachedRolePolicies",
      "iam:CreateServiceLinkedRole",
      "iam:DeleteServiceLinkedRole",
      "iam:GetRole",
      "iam:GetPolicy",
      "iam:GetPolicyVersion",
      "kms:DescribeKey",
      "organizations:DescribeOrganization",
      "account:ListRegions",
      "rds:Describe*",
      "route53:Get*",
      "route53:List*",
      "route53:Test*",
    ])

    resources = [
      "*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }

  statement {
    sid = "S3ConsoleAccess"

    effect = "Allow"

    actions = [
      "s3:GetAccountPublicAccessBlock",
      "s3:GetBucketAcl",
      "s3:GetBucketLocation",
      "s3:GetBucketPolicyStatus",
      "s3:GetBucketPublicAccessBlock",
      "s3:ListAllMyBuckets",
    ]

    resources = [
      "*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }

  statement {
    sid = "S3ListObjectsInBucket"

    effect = "Allow"

    actions = [
      "s3:ListBucket",
    ]

    resources = [
      "arn:aws:s3:::*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }

  statement {
    sid = "S3AllObjectActions"

    effect = "Allow"

    actions = [
      "s3:*Object",
    ]

    resources = [
      "arn:aws:s3:::*/*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }
  statement {
    sid    = "AllowAssumeRole"
    effect = "Allow"
    actions = [
      "sts:AssumeRole",
    ]
    resources = [
      "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/*",
    ]
  }

  statement {
    sid    = "AllowUsingKMSKeysViaLambdaService"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
    ]
    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["lambda.${var.region}.amazonaws.com"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:ResourceTag/application_family"
      values   = [var.application_family]
    }
    resources = ["arn:aws:kms:*:${data.aws_caller_identity.current.account_id}:*"]
  }
}

data "aws_iam_policy_document" "power_user" {
  count = var.require_mfa ? 0 : 1

  statement {
    sid = "AllowEverythingExceptDestructActions"

    effect = "Allow"

    not_actions = [
      "iam:*",
      "organizations:*",
      "account:*",
      "kms:*",
      "rds:*",
      "guardduty:*",
      "cloudtrail:*",
      "secretsmanager:*",
      "route53:*",
      "ec2:Delete*",
      "ec2:Terminate*",
      "ecs:Delete*",
      "ecr:Delete*",
      "athena:Delete*",
      "elasticloadbalancing:Delete*",
      "acm:Delete*",
      "cloudfront:Delete*",
      "elasticache:Delete*",
      "s3:Create*",
      "ec2:CreateSecurityGroup",
    ]

    resources = [
      "*",
    ]
  }

  statement {
    sid = "AllowReadActions"

    effect = "Allow"

    actions = [
      "iam:ListRoles",
      "iam:PassRole",
      "iam:ListRolePolicies",
      "iam:ListAttachedRolePolicies",
      "iam:CreateServiceLinkedRole",
      "iam:DeleteServiceLinkedRole",
      "iam:GetRole",
      "iam:GetPolicy",
      "iam:GetPolicyVersion",
      "kms:DescribeKey",
      "organizations:DescribeOrganization",
      "account:ListRegions",
      "rds:Describe*",
      "route53:Get*",
      "route53:List*",
      "route53:Test*",
    ]

    resources = [
      "*",
    ]
  }

  statement {
    sid = "S3ConsoleAccess"

    effect = "Allow"

    actions = [
      "s3:GetAccountPublicAccessBlock",
      "s3:GetBucketAcl",
      "s3:GetBucketLocation",
      "s3:GetBucketPolicyStatus",
      "s3:GetBucketPublicAccessBlock",
      "s3:ListAllMyBuckets",
    ]

    resources = [
      "*",
    ]
  }

  statement {
    sid = "S3ListObjectsInBucket"

    effect = "Allow"

    actions = [
      "s3:ListBucket",
    ]

    resources = [
      "arn:aws:s3:::*",
    ]
  }

  statement {
    sid = "S3AllObjectActions"

    effect = "Allow"

    actions = [
      "s3:*Object"
    ]

    resources = [
      "arn:aws:s3:::*/*",
    ]
  }

  statement {
    sid    = "AllowUsingKMSKeysViaLambdaService"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
    ]
    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["lambda.${var.region}.amazonaws.com"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:ResourceTag/application_family"
      values   = [var.application_family]
    }
    resources = ["arn:aws:kms:*:${data.aws_caller_identity.current.account_id}:*"]
  }
}
