
#############################################
### LDAP                                  ###
#############################################

# Helper Variables:
# Keep in mind to mapp this variables if there is ever the possibility for the user to define them in the inventory
LDAP_DN_BASE:                 "{{ PRIMARY_DOMAIN.split('.') | map('regex_replace', '^(.*)$', 'dc=\\1') | join(',') }}"
_ldap_docker_network_enabled: "{{ applications | get_app_conf('svc-db-openldap', 'network.docker') }}"
_ldap_protocol:               "{{ 'ldap' if _ldap_docker_network_enabled else 'ldaps' }}"
_ldap_server_port:            "{{ ports.localhost[_ldap_protocol]['svc-db-openldap'] }}"
_ldap_name:                   "{{ applications | get_app_conf('svc-db-openldap', 'docker.services.openldap.name') }}"
_ldap_domain:                 "{{ PRIMARY_DOMAIN }}" # LDAP is jsut listening to a port not to a dedicated domain, so primary domain should be sufficient
_ldap_user_id:                "uid"
_ldap_filters_users_all:      "(|(objectclass=inetOrgPerson))"

ldap:
  # Distinguished Names (DN)
  dn:
    # -------------------------------------------------------------------------
    # Base DN / Suffix
    # This is the top-level naming context for your directory, used as the
    # default search base for most operations (e.g. adding users, groups).
    # Example: “dc=example,dc=com”
    root:               "{{ LDAP_DN_BASE }}"
    administrator:
      # -------------------------------------------------------------------------
      # Data-Tree Administrator Bind DN
      # The DN used to authenticate for regular directory operations under
      # the data tree (adding users, modifying attributes, creating OUs, etc.).
      # Typically: “cn=admin,dc=example,dc=com”
      data: "cn={{ applications['svc-db-openldap'].users.administrator.username }},{{ LDAP_DN_BASE }}"

      # -------------------------------------------------------------------------
      # Config-Tree Administrator Bind DN
      # The DN used to authenticate against the cn=config backend when you
      # need to load or modify schema, overlays, modules, or other server-
      # level settings.  
      # Typically: “cn=admin,cn=config”
      configuration: "cn={{ applications['svc-db-openldap'].users.administrator.username }},cn=config"

    ou:
      # -------------------------------------------------------------------------
      # Organizational Units (OUs)
      # Pre-created containers in the directory tree to logically separate entries:
      # – users:  Contains all user objects (person/posixAccount entries).
      # – groups: Contains organizational or business groups (e.g., departments, teams).
      # – roles:  Contains application-specific RBAC roles 
      #           (e.g., "cn=app1-user", "cn=yourls-admin").
      users:   "ou=users,{{ LDAP_DN_BASE }}"
      groups:  "ou=groups,{{ LDAP_DN_BASE }}"
      roles:   "ou=roles,{{ LDAP_DN_BASE }}"

    # -------------------------------------------------------------------------
    # Additional Notes
    # – Always bind as data_admin for CRUD on entries under your base DN.
    # – Always bind as config_admin when you push schema-level LDIFs via ldapi:///
    # – Keeping these distinct prevents accidental use of config credentials
    #   for ordinary user/group operations, and vice versa.

  # Password to access dn.bind
  bind_credential:      "{{ applications | get_app_conf('svc-db-openldap', 'credentials.administrator_database_password') }}"
  server:
    domain:             "{{ _ldap_name if _ldap_docker_network_enabled else _ldap_domain }}" # Mapping for public or locale access
    port:               "{{ _ldap_server_port }}"
    uri:                "{{ _ldap_protocol }}://{{ _ldap_name if _ldap_docker_network_enabled else _ldap_domain }}:{{ _ldap_server_port }}"
    security:           "" #TLS, SSL - Leave empty for none
  network:
    local:              "{{ _ldap_docker_network_enabled }}" # Uses the application configuration to define if local network should be available or not
  user:
    objects:
      structural:
        - person            # Structural Classes define the core identity of an entry:
                            # • Specify mandatory attributes (e.g. sn, cn)
                            # • Each entry must have exactly one structural class
        - inetOrgPerson     # An extension of person adding internet-related attributes
                            # (e.g. mail, employeeNumber)
        - posixAccount      # Provides UNIX account attributes (uidNumber, gidNumber,
                            # homeDirectory)
      auxiliary:
        nextloud_user:  "nextcloudUser"   # Auxiliary Classes attach optional attributes without
                                          # changing the entry’s structural role. Here they add
                                          # nextcloudQuota and nextcloudEnabled for Nextcloud.
        ssh_public_key: "ldapPublicKey"   # Allows storing SSH public keys for services like Gitea.
    attributes:
      # Attribut to identify the user
      id:                 "{{ _ldap_user_id }}"
      mail:               "mail"
      fullname:           "cn"
      firstname:          "givenname"
      surname:            "sn"
      ssh_public_key:     "sshPublicKey"
      nextcloud_quota:    "nextcloudQuota"
  filters:
    users:
      login:            "(&{{ _ldap_filters_users_all }}({{_ldap_user_id}}=%{{_ldap_user_id}}))"
      all:              "{{ _ldap_filters_users_all }}"
  rbac:
    flavors:
      # Valid values posixGroup, groupOfNames
      - groupOfNames
      # - posixGroup
