Skip to content

Conversation

Amphaal
Copy link

@Amphaal Amphaal commented Feb 23, 2025

Would fix #2314

@knadh
Copy link
Owner

knadh commented Feb 26, 2025

Thanks for the PR @Amphaal. API secrets are randomly generated, so it doesn't seem right to pass a manually constructed random looking secret into the DB from the CLI. Doesn't seem semantically right.

I do agree that it'd be good to have a way to generate a fully capable API user programmatically.

Would be good to know how other apps approach this. Have you seen examples?

@Amphaal
Copy link
Author

Amphaal commented Feb 27, 2025

No problem @knadh !

I agree with you, this is kind of an hack to allow "admin" permissions - like we would have pre v4 - which allows me to setup listmonk using automation.

What I am used to regarding token usage are:

  • Pre-generated "admin" API token somewhere on the container triggered by ENV parameterization, that we need to extract via volume binding on a specific path
  • Short-lived generation of tokens via a POST request (for example on /login/generateToken) that we would trigger using the classic Authorization auth method of existing admin user-password pair

Regarding current implementation, the first solution seems to fit. Let me know your thoughts about this !

@knadh
Copy link
Owner

knadh commented Mar 4, 2025

Thanks @Amphaal. API tokens are auto-generated strings, so passing a manually constructed string seems off. It then allows for string patterns (including proper words) to be passed as tokens, which technically is fine, but semantically, incorrect.

I think a more semantic, but slightly clunky approach is to auto-generate a token (when LISTMONK_ADMIN_API_USER is set) and print it to stdout, which can then be captured and extracted. This is a standard practice as well (eg: openssl CLI).

@knadh
Copy link
Owner

knadh commented Mar 12, 2025

Hi @Amphaal. Would you be able to amend the PR with a LISTMONK_ADMIN_API=true approach?

@Amphaal
Copy link
Author

Amphaal commented Mar 12, 2025

hi @knadh, sure ! Been under the water the past 2 weeks, but I should be able to push something nice this weekend :) If not, do not hesitate to ping back !

@ton77v
Copy link

ton77v commented Apr 9, 2025

Are there any workarounds while this is not implemented? I wrote a little shell script inserting the API user into the DB, but for some reasons auth won't work for him

However, if I log in manually as superuser and add another user in the dashboard, the original API user auth magically starts working 😀

The issue is that I need this for integration tests in CI so using dashboard is a bit problematic

@Amphaal
Copy link
Author

Amphaal commented Apr 9, 2025

Are there any workarounds while this is not implemented? I wrote a little shell script inserting the API user into the DB, but for some reasons auth won't work for him

However, if I log in manually as superuser and add another user in the dashboard, the original API user auth magically starts working 😀

The issue is that I need this for integration tests in CI so using dashboard is a bit problematic

Hi, still under the water, but just a quick heads-up; I used a workaround for my CI / IaC (using Ansible), and it looks like this:

##
## Await for listmonk to create database
##

- name: Wait for pod to become ready
  ansible.builtin.command: |
    kubectl wait
    pods -l app={{ k8s__listmonk__app_name }}
    --namespace={{ k8s__listmonk__namespace }}
    --for=condition=Ready
    --timeout=240s
  register: pods_ready
  changed_when: pods_ready.rc != 0

##
## Create API user
##

- name: Install prerequisites to use "community.postgresql.postgresql_query"
  ansible.builtin.apt:
    state: present
    update_cache: true
    package:
      - postgresql
      - libpq-dev
      - python3-psycopg2

- name: Create API User
  community.postgresql.postgresql_query:
    db: "{{ k8s__listmonk__db__db }}"
    login_user: "{{ k8s__listmonk__db__user }}"
    login_password: "{{ k8s__listmonk__db__password }}"
    login_host: "{{ k8s__listmonk__internal_hostname__db }}"
    login_port: 5432
    positional_args:
      - "{{ k8s__listmonk__admin_api__username }}"
      - "{{ k8s__listmonk__admin_api__password }}"
      - "{{ k8s__listmonk__admin_api__username }}@listmonk"
      - Admin API
    query: >
      INSERT INTO users (username, password_login, password, email, name, type, user_role_id, list_role_id, status)
      VALUES(%s, false, %s, %s, %s, 'api', 1, NULL, 'enabled')
      ON CONFLICT (username) DO NOTHING;

##
## Requires restarting for listmonk to ack
##

- name: Sundown listmonk
  kubernetes.core.k8s_scale:
    api_version: v1
    kind: Deployment
    name: "{{ k8s__listmonk__app_name }}"
    namespace: "{{ k8s__listmonk__namespace }}"
    replicas: 0
    wait: true

- name: Reset listmonk
  kubernetes.core.k8s_scale:
    api_version: v1
    kind: Deployment
    name: "{{ k8s__listmonk__app_name }}"
    namespace: "{{ k8s__listmonk__namespace }}"
    replicas: 1
    wait: true

This worked for me in the meantime.

knadh added a commit that referenced this pull request Apr 10, 2025
- During install, listmonk now accepts the env `LISTMONK_ADMIN_API_USER`
  and creates an API user (with username $LISTMONK_ADMIN_API_USER)
  with full superadmin permissions. This requires LISTMONK_ADMIN_USER and
  LISTMONK_ADMIN_API_PASSWORD to be set so that that there's always a superadmin
  user to avoid bad states, mainly: bot superadmin exists, but no admin user
  exists, leaving the installation perpetually open with the superadmin user
  creation UI on the first login.
  The API user's token is printed to stderr in the following format:
  `export LISTMONK_ADMIN_API_TOKEN="7I81VSd90UWhKDj5Kq9c6YopToRduyDF"`
  This can be redirected to a file with ./listmonk 2> /tmp/token or captured
  directly and then source()'d.
- Add new function `core.GetRole(id)`.
- Fix `at least one super admin` query in user deletion.
@knadh
Copy link
Owner

knadh commented Apr 10, 2025

This feature is merged in 562e52c. Please see #2314 (comment) for details.

Thank you for kick starting this with the PR @Amphaal! 🎉

@knadh knadh closed this Apr 10, 2025
@Amphaal
Copy link
Author

Amphaal commented Apr 10, 2025

Many thanks for taking care of this @knadh 👍

Bowrna pushed a commit to Bowrna/listmonk that referenced this pull request Apr 15, 2025
…knadh#2322.

- During install, listmonk now accepts the env `LISTMONK_ADMIN_API_USER`
  and creates an API user (with username $LISTMONK_ADMIN_API_USER)
  with full superadmin permissions. This requires LISTMONK_ADMIN_USER and
  LISTMONK_ADMIN_API_PASSWORD to be set so that that there's always a superadmin
  user to avoid bad states, mainly: bot superadmin exists, but no admin user
  exists, leaving the installation perpetually open with the superadmin user
  creation UI on the first login.
  The API user's token is printed to stderr in the following format:
  `export LISTMONK_ADMIN_API_TOKEN="7I81VSd90UWhKDj5Kq9c6YopToRduyDF"`
  This can be redirected to a file with ./listmonk 2> /tmp/token or captured
  directly and then source()'d.
- Add new function `core.GetRole(id)`.
- Fix `at least one super admin` query in user deletion.
Bowrna pushed a commit to Bowrna/listmonk that referenced this pull request Apr 16, 2025
…knadh#2322.

- During install, listmonk now accepts the env `LISTMONK_ADMIN_API_USER`
  and creates an API user (with username $LISTMONK_ADMIN_API_USER)
  with full superadmin permissions. This requires LISTMONK_ADMIN_USER and
  LISTMONK_ADMIN_API_PASSWORD to be set so that that there's always a superadmin
  user to avoid bad states, mainly: bot superadmin exists, but no admin user
  exists, leaving the installation perpetually open with the superadmin user
  creation UI on the first login.
  The API user's token is printed to stderr in the following format:
  `export LISTMONK_ADMIN_API_TOKEN="7I81VSd90UWhKDj5Kq9c6YopToRduyDF"`
  This can be redirected to a file with ./listmonk 2> /tmp/token or captured
  directly and then source()'d.
- Add new function `core.GetRole(id)`.
- Fix `at least one super admin` query in user deletion.
Bowrna added a commit to Bowrna/listmonk that referenced this pull request Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create API user through script/command line
3 participants