02_webadmin.ymlΒΆ

---
# The WebUI bundle (a JMAP "Application" record) is staged locally in 00_core;
# point the record's resourceUrl at that file:// path and re-unpack.

- name: "πŸ“– List Stalwart Application records and OAuth clients"
  include_tasks: jmap_call.yml
  vars:
    stalwart_jmap_body: >-
      {{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
          'methodCalls': [['x:Application/get', {'ids': none}, 'Application'],
                          ['x:OAuthClient/get', {'ids': none}, 'OAuthClient']]} | to_json }}

- name: "πŸ” Resolve the WebUI Application record"
  ansible.builtin.set_fact:
    stalwart_webui_apps: >-
      {{ stalwart_jmap.methodResponses[0][1].list
         | selectattr('description', 'equalto', STALWART_WEBUI_APP_DESCRIPTION)
         | list }}

- name: "βœ… Ensure the WebUI Application record was found"
  ansible.builtin.assert:
    that:
      - stalwart_webui_apps | length > 0
    fail_msg: >-
      No Stalwart Application record with description
      '{{ STALWART_WEBUI_APP_DESCRIPTION }}' among the records this Stalwart
      reports:
      {{ stalwart_jmap.methodResponses[0][1].list | map(attribute='description') | list }}
    quiet: true

- name: "πŸ” Resolve the WebUI Application id"
  ansible.builtin.set_fact:
    stalwart_webui_app_id: "{{ stalwart_webui_apps[0].id }}"

- name: "πŸ” Resolve the WebUI OAuth client"
  ansible.builtin.set_fact:
    stalwart_webui_oauth_client: "{{ lookup('template', 'jmap/oauth_client/webui.json.j2') | from_json }}"
    stalwart_webui_oauth_clients: >-
      {{ stalwart_jmap.methodResponses[1][1].list
         | selectattr('clientId', 'equalto', STALWART_WEBUI_OAUTH_CLIENT_ID)
         | list }}
  vars:
    stalwart_webui_origins: "{{ lookup('network_urls', STALWART_WEBUI_BASE_URL) }}"
    stalwart_webui_url_prefixes: "{{ stalwart_webui_apps[0].urlPrefix | list }}"

- name: "πŸ“ Register the WebUI OAuth client"
  include_tasks: jmap_call.yml
  vars:
    stalwart_jmap_body: "{{ lookup('template', 'jmap/oauth_client/create.json.j2') }}"
  when: stalwart_webui_oauth_clients | length == 0

- name: "πŸ”„ Align the WebUI OAuth client with the origin the WebUI is served from"
  include_tasks: jmap_call.yml
  vars:
    stalwart_jmap_body: "{{ lookup('template', 'jmap/oauth_client/update.json.j2') }}"
  when:
    - stalwart_webui_oauth_clients | length > 0
    - >-
      (stalwart_webui_oauth_clients[0] | dict2items
       | selectattr('key', 'in', stalwart_webui_oauth_client) | items2dict)
      != stalwart_webui_oauth_client

- name: "πŸ”— Point the WebUI Application at the locally-staged bundle and its OAuth client"
  include_tasks: jmap_call.yml
  vars:
    stalwart_jmap_body: >-
      {{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
          'methodCalls': [['x:Application/set',
            {'update': {stalwart_webui_app_id: {'resourceUrl': STALWART_WEBUI_LOCAL_URL,
                                                'oauthClientId': STALWART_WEBUI_OAUTH_CLIENT_ID}}},
            'c0']]} | to_json }}

- name: "πŸ“¦ Unpack the WebUI bundle from the local file"
  include_tasks: jmap_call.yml
  vars:
    stalwart_jmap_body: >-
      {{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
          'methodCalls': [['x:Action/set',
            {'create': {'a': {'@type': 'UpdateApps'}}},
            'c0']]} | to_json }}

- name: "πŸ”§ Verify the WebAdmin is served after unpack"
  ansible.builtin.shell: >-
    container exec -i {{ STALWART_CONTAINER_ADDRESS }}
    {{ 30 | curl }} -sS -o /dev/null -w "%{http_code}" {{ STALWART_LOCAL_BASE_URL }}/
  register: stalwart_webui_probe
  changed_when: false
  retries: 6
  delay: 5
  until: stalwart_webui_probe.stdout in ['200', '301', '302']