module "authelia" {
  source = "../services/service"

  name                = "authelia"
  instance_count      = 2
  priority            = 70
  image               = "authelia/authelia:4.37"
  args                = ["--config", "$${NOMAD_TASK_DIR}/authelia.yml"]
  ingress             = true
  service_port        = 9999
  service_port_static = true
  use_wesher          = var.use_wesher
  # metrics_port = 9959

  env = {
    AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE       = "$${NOMAD_SECRETS_DIR}/ldap_password.txt"
    AUTHELIA_JWT_SECRET_FILE                                 = "$${NOMAD_SECRETS_DIR}/jwt_secret.txt"
    AUTHELIA_SESSION_SECRET_FILE                             = "$${NOMAD_SECRETS_DIR}/session_secret.txt"
    AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE                     = "$${NOMAD_SECRETS_DIR}/storage_encryption_key.txt"
    AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE                     = "$${NOMAD_SECRETS_DIR}/mysql_password.txt"
    AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE                     = "$${NOMAD_SECRETS_DIR}/smtp_password.txt"
    AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE        = "$${NOMAD_SECRETS_DIR}/oidc_hmac_secret.txt"
    AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE = "$${NOMAD_SECRETS_DIR}/oidc_issuer_private_key.txt"
    # AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE  = "$${NOMAD_SECRETS_DIR}/oidc_issuer_certificate_chain.txt"
  }

  use_mysql = true
  use_ldap  = true
  use_redis = true
  use_smtp  = true
  mysql_bootstrap = {
    enabled = true
  }

  service_tags = [
    # Configure traefik to add this middleware
    "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia.nomad:$${NOMAD_PORT_main}/api/verify?rd=https%3A%2F%2Fauthelia.${var.base_hostname}%2F",
    "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true",
    "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email",
    "traefik.http.middlewares.authelia-basic.forwardAuth.address=http://authelia.nomad:$${NOMAD_PORT_main}/api/verify?auth=basic",
    "traefik.http.middlewares.authelia-basic.forwardAuth.trustForwardHeader=true",
    "traefik.http.middlewares.authelia-basic.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email",
  ]

  templates = [
    {
      data  = file("${path.module}/authelia.yml")
      dest  = "authelia.yml"
      mount = false
    },
    {
      data        = "{{ with nomadVar \"secrets/ldap\" }}{{ .admin_password }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "ldap_password.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .jwt_secret }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "jwt_secret.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .session_secret }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "session_secret.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .storage_encryption_key }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "storage_encryption_key.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .db_pass }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "mysql_password.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .oidc_hmac_secret }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "oidc_hmac_secret.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .oidc_issuer_private_key }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "oidc_issuer_private_key.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"nomad/jobs/authelia\" }}{{ .oidc_issuer_certificate_chain }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "oidc_issuer_certificate_chain.txt"
      mount       = false
    },
    {
      data        = "{{ with nomadVar \"secrets/smtp\" }}{{ .password }}{{ end }}"
      dest_prefix = "$${NOMAD_SECRETS_DIR}"
      dest        = "smtp_password.txt"
      mount       = false
    },
  ]
}

resource "nomad_acl_policy" "authelia" {
  name        = "authelia"
  description = "Give access to shared authelia variables"
  rules_hcl   = <<EOH
namespace "default" {
  variables {
    path "authelia/*" {
      capabilities = ["read"]
    }
    path "secrets/authelia/*" {
      capabilities = ["read"]
    }
  }
}
EOH

  job_acl {
    job_id = module.authelia.job_id
  }
}

# Give access to ldap secrets
resource "nomad_acl_policy" "authelia_ldap_secrets" {
  name        = "authelia-secrets-ldap"
  description = "Give access to LDAP secrets"
  rules_hcl   = <<EOH
namespace "default" {
  variables {
    path "secrets/ldap" {
      capabilities = ["read"]
    }
  }
}
EOH

  job_acl {
    job_id = module.authelia.job_id
  }
}

# Enable oidc for nomad clients
module "nomad_oidc_client" {
  source = "./oidc_client"

  name = "nomad"
  oidc_client_config = {
    description          = "Nomad"
    authorization_policy = "two_factor"
    redirect_uris = [
      "https://nomad.${var.base_hostname}/oidc/callback",
      "https://nomad.${var.base_hostname}/ui/settings/tokens",
    ]
    scopes = ["openid", "groups"]
  }
}

resource "nomad_acl_auth_method" "nomad_authelia" {
  name           = "authelia"
  type           = "OIDC"
  token_locality = "global"
  max_token_ttl  = "1h0m0s"
  default        = true

  config {
    oidc_discovery_url = "https://authelia.${var.base_hostname}"
    oidc_client_id     = module.nomad_oidc_client.client_id
    oidc_client_secret = module.nomad_oidc_client.secret
    bound_audiences    = ["nomad"]
    oidc_scopes = [
      "groups",
      "openid",
    ]
    allowed_redirect_uris = [
      "https://nomad.${var.base_hostname}/oidc/callback",
      "https://nomad.${var.base_hostname}/ui/settings/tokens",
    ]
    list_claim_mappings = {
      "groups" : "roles"
    }
  }
}

resource "nomad_acl_binding_rule" "nomad_authelia_admin" {
  description = "engineering rule"
  auth_method = nomad_acl_auth_method.nomad_authelia.name
  selector    = "\"nomad-deploy\" in list.roles"
  bind_type   = "role"
  bind_name   = "admin" # acls.nomad_acl_role.admin.name
}

resource "nomad_acl_binding_rule" "nomad_authelia_deploy" {
  description = "engineering rule"
  auth_method = nomad_acl_auth_method.nomad_authelia.name
  selector    = "\"nomad-deploy\" in list.roles"
  bind_type   = "role"
  bind_name   = "deploy" # acls.nomad_acl_role.deploy.name
}