locals {
  guardduty_detector_arns = [
    /* aws_guardduty_detector.guardduty_ap_northeast_1.arn,
    aws_guardduty_detector.guardduty_ap_northeast_2.arn,
    aws_guardduty_detector.guardduty_ap_northeast_3.arn,
    aws_guardduty_detector.guardduty_ap_south_1.arn,
    aws_guardduty_detector.guardduty_ap_southeast_1.arn,
    aws_guardduty_detector.guardduty_ap_southeast_2.arn,
    aws_guardduty_detector.guardduty_ca_central_1.arn, */
    aws_guardduty_detector.guardduty_eu_central_1.arn,
    /* aws_guardduty_detector.guardduty_eu_north_1.arn,
    aws_guardduty_detector.guardduty_eu_west_1.arn,
    aws_guardduty_detector.guardduty_eu_west_2.arn,
    aws_guardduty_detector.guardduty_eu_west_3.arn,
    aws_guardduty_detector.guardduty_sa_east_1.arn, */
    aws_guardduty_detector.guardduty_us_east_1.arn,
    aws_guardduty_detector.guardduty_us_east_2.arn,
    aws_guardduty_detector.guardduty_us_west_1.arn,
    aws_guardduty_detector.guardduty_us_west_2.arn,
  ]
}

data "aws_iam_policy_document" "guardduty_kms_key_policy" {
  # checkov:skip=CKV_AWS_109:It is a KMS key policy, so it applies only to a specific key.
  # checkov:skip=CKV_AWS_111:The same as above.
  statement {
    sid       = "Enable IAM User Permissions"
    effect    = "Allow"
    resources = ["*"]
    actions = [
      "kms:*",
    ]

    principals {
      type = "AWS"
      identifiers = [
        "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root",
      ]
    }
  }

  statement {
    sid       = "Allow GuardDuty to use key"
    effect    = "Allow"
    resources = ["*"]
    actions = [
      "kms:GenerateDataKey",
    ]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = local.guardduty_detector_arns
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceAccount"
      values   = [data.aws_caller_identity.current.account_id]
    }
  }
}

module "guardduty_logs_bucket" {
  source = "git@github.com:theorchard/terraform-gsirt.git//modules/access_logs?ref=2.3.2"
  providers = {
    aws = aws.us_east_1
  }

  environment                   = var.environment
  service_name                  = var.account_group
  access_log_type               = "guardduty"
  kms_override_policy_documents = [data.aws_iam_policy_document.guardduty_kms_key_policy.json]
  bucket_policy_overrides       = [data.aws_iam_policy_document.guardduty_bucket_policy_document.json]
}

data "aws_iam_policy_document" "guardduty_bucket_policy_document" {
  statement {
    sid       = "Deny non-HTTPS access"
    effect    = "Deny"
    resources = ["${module.guardduty_logs_bucket.access_logs_bucket_arn}/*"]
    actions   = ["s3:*"]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values   = ["false"]
    }
  }

  statement {
    sid       = "Deny incorrect encryption header"
    effect    = "Deny"
    resources = ["${module.guardduty_logs_bucket.access_logs_bucket_arn}/*"]
    actions   = ["s3:PutObject"]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "StringNotEquals"
      variable = "s3:x-amz-server-side-encryption-aws-kms-key-id"
      values   = [module.guardduty_logs_bucket.access_logs_kms_key_arn]
    }
  }

  statement {
    sid       = "Deny unencrypted object uploads"
    effect    = "Deny"
    resources = ["${module.guardduty_logs_bucket.access_logs_bucket_arn}/*"]
    actions   = ["s3:PutObject"]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "StringNotEquals"
      variable = "s3:x-amz-server-side-encryption"
      values   = ["aws:kms"]
    }
  }

  statement {
    sid       = "Allow PutObject"
    effect    = "Allow"
    resources = ["${module.guardduty_logs_bucket.access_logs_bucket_arn}/*"]
    actions   = ["s3:PutObject"]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = local.guardduty_detector_arns
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceAccount"
      values   = [data.aws_caller_identity.current.account_id]
    }
  }

  statement {
    sid       = "Allow GetBucketLocation"
    effect    = "Allow"
    resources = [module.guardduty_logs_bucket.access_logs_bucket_arn]
    actions   = ["s3:GetBucketLocation"]

    principals {
      type = "Service"
      identifiers = [
        "guardduty.amazonaws.com",
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = local.guardduty_detector_arns
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceAccount"
      values   = [data.aws_caller_identity.current.account_id]
    }
  }
}
