--- # 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.