computer-playbook/roles/docker-mailu/tasks/create-mailu-user-and-token.yml

72 lines
2.8 KiB
YAML

---
# tasks/create-mailu-user-and-token.yml
#
# Ensures a Mailu user exists and idempotently creates an API token for them,
# storing tokens in a dictionary for targeted access.
#
# Required variables:
# mailu_compose_dir: Path to your docker-compose.yml directory
# mailu_user: Local part of the user (e.g., "alice")
# mailu_domain: Domain for the user (e.g., "example.com")
# mailu_password: Password for the new user
# mailu_api_base_url: Base URL of the Mailu API (e.g., "https://mail.example.com/api/v1")
# mailu_global_api_token: Global API token (from API_TOKEN environment variable)
#
# Optional variable:
# mailu_user_tokens: Dictionary of existing tokens, e.g. { "alice": "secret" }
- name: "Ensure Mailu user {{ mailu_user }}@{{ mailu_domain }} exists"
command: >
docker compose exec admin flask mailu {{ mailu_action }} {{ mailu_user }} {{ mailu_domain }} '{{ mailu_password }}'
args:
chdir: "{{ mailu_compose_dir }}"
register: mailu_user_creation
failed_when: false
changed_when: mailu_user_creation.rc == 0 and 'User added' in mailu_user_creation.stdout
- name: "Fetch existing API tokens"
uri:
url: "{{ mailu_api_base_url }}/tokens"
method: GET
headers:
Authorization: "Bearer {{ mailu_global_api_token }}"
return_content: yes
register: mailu_tokens_response
failed_when: mailu_tokens_response.status not in [200]
- name: "Extract existing token info for {{ mailu_user }}"
set_fact:
mailu_user_existing_token: >
{{ mailu_tokens_response.json
| selectattr('comment', 'equalto', mailu_user)
| list
| first }}
- name: "Create API token for {{ mailu_user }} if none exists"
uri:
url: "{{ mailu_api_base_url }}/tokens"
method: POST
headers:
Authorization: "Bearer {{ mailu_global_api_token }}"
Content-Type: "application/json"
body_format: json
body:
comment: "{{ mailu_user }}"
ip: "{{ mailu_token_ip }}"
status_code: 201
register: mailu_token_creation
when: mailu_user_existing_token is not defined
- name: "Set mailu_user_tokens dictionary"
set_fact:
mailu_user_tokens: >
{{ (mailu_user_tokens | default({}))
| combine({ mailu_user: ((mailu_token_creation is defined)
| ternary(mailu_token_creation.json.secret,
mailu_user_existing_token.secret)) }) }}
# Note:
# - GET /tokens returns only metadata (id, comment, ip, created), not the secret itself.
# - The secret is returned only by the POST request and must be captured when created.
# - Tokens are stored in the mailu_user_tokens dictionary for targeted access.
# - Persist mailu_user_tokens securely (e.g., in Ansible Vault) for future use.