Files
computer-playbook/roles/web-app-nextcloud/tasks/addons/user_ldap.yml
kevinveenbirkenbachandClaude Opus 5 3a1f11fac8 fix(nextcloud): resolve the admin LDAP identities synchronously
07_admin_identities.yml registered 'occ ldap:search <admin>' with async/poll, and ASYNC_POLL is 0 whenever ASYNC_ENABLED is true. The register then holds an async job handle with no stdout, and thirteen lines later the set_fact parses exactly that stdout for the '(identity)' pattern. The list therefore collapsed to [NEXTCLOUD_ADMINISTRATOR_USERNAME] on every swarm run, the LDAP-mapped administrator_<n> never entered the admin group, and failed_when could not complain because it is keyed on the same global flag.

The symptom is a 403 on every admin-scoped route while user routes return 200. The Playwright trace of one session carries data-user=administrator_2981 and _oc_isadmin=false on BOTH - and _oc_isadmin comes straight from IGroupManager::isAdmin(), so it states the group membership rather than the route's verdict. The compose lane stays green only because it runs a synchronous pass first, where the same task does have stdout and adds administrator_3447; its later async pass degenerates identically.

Three tasks become synchronous: the identity resolution, the group:adduser loop that writes the membership, and the LDAP cache warm in addons/user_ldap.yml whose task name promises the users are present. Measured cost 2.533 s + 0.730 s against a 2:30:13 job. The 'not ASYNC_ENABLED and' guards stay: they hang on the global flag, not on the task being async, so removing async does not arm them.

The condition moves into NEXTCLOUD_USER_LDAP_ENABLED and the two tasks sharing it into one block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:04:15 +02:00

60 lines
2.7 KiB
YAML

---
# @See https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html
- name: 🔍 Resolve desired Nextcloud LDAP config ID
set_fact:
nextcloud_ldap_config_id: "{{ (NEXTCLOUD_LDAP_CONFIG_PREFIX | default('s01')) | string | trim }}"
changed_when: false
- name: 🔎 Check if desired Nextcloud LDAP config ID exists
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:show-config {{ nextcloud_ldap_config_id }}
register: nextcloud_ldap_config_probe
changed_when: false
failed_when: false
- name: 🛑 Fail when LDAP config probe failed for unexpected reason
fail:
msg: >-
Could not verify Nextcloud LDAP config '{{ nextcloud_ldap_config_id }}'.
stdout='{{ nextcloud_ldap_config_probe.stdout }}'
stderr='{{ nextcloud_ldap_config_probe.stderr }}'
when:
- nextcloud_ldap_config_probe.rc != 0
- "'Invalid configID' not in ((nextcloud_ldap_config_probe.stdout) ~ (nextcloud_ldap_config_probe.stderr))"
- name: 📁 Auto-create empty Nextcloud LDAP config when desired config ID is missing
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:create-empty-config
register: nextcloud_ldap_config_create
changed_when: nextcloud_ldap_config_create.rc == 0
when:
- nextcloud_ldap_config_probe.rc != 0
- "'Invalid configID' in ((nextcloud_ldap_config_probe.stdout) ~ (nextcloud_ldap_config_probe.stderr))"
- name: 🔎 Re-check desired Nextcloud LDAP config ID after auto-create
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:show-config {{ nextcloud_ldap_config_id }}
register: nextcloud_ldap_config_reprobe
changed_when: false
failed_when: false
when:
- nextcloud_ldap_config_create is defined
- nextcloud_ldap_config_create is changed
- name: 🛑 Fail when desired LDAP config ID is still missing after auto-create
assert:
that:
- nextcloud_ldap_config_reprobe.rc == 0
fail_msg: >-
Nextcloud LDAP config '{{ nextcloud_ldap_config_id }}' is still missing after auto-create.
create_stdout='{{ nextcloud_ldap_config_create.stdout | default('') }}'
create_stderr='{{ nextcloud_ldap_config_create.stderr | default('') }}'
when:
- nextcloud_ldap_config_create is defined
- nextcloud_ldap_config_create is changed
- name: 🔧 Set Nextcloud LDAP bind password
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:set-config {{ nextcloud_ldap_config_id }} ldapAgentPassword '{{ LDAP.BIND_CREDENTIAL }}'
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: 🟢 Activate Nextcloud LDAP configuration
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:set-config {{ nextcloud_ldap_config_id }} ldapConfigurationActive 1
- name: 🗂️ Warm LDAP cache (to guaranty that all LDAP users are present)
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} ldap:search ""