Skip to content

PT-079: XNAT set-password invite link (no emailed password) + enclave branding - #977

Draft
atriaybagur wants to merge 2 commits into
developfrom
pt079-xnat-invite-link-and-branding
Draft

PT-079: XNAT set-password invite link (no emailed password) + enclave branding#977
atriaybagur wants to merge 2 commits into
developfrom
pt079-xnat-invite-link-and-branding

Conversation

@atriaybagur

Copy link
Copy Markdown
Member

Summary

Addresses FLIP-PT-079 (High — plaintext XNAT passwords emailed via SES) and, alongside it, brands the mocked enclave XNAT so users can tell which trust they are on.

Two logical commits:

  1. security(pt-079) — email a set-password invite link instead of a password.
  2. feat(xnat) — trust-named site description + FLIP logo on the XNAT login page.

PT-079 — invite link, never a password

Previously the hub decrypted the generated XNAT account password and emailed it in cleartext via SES, so anyone able to read the mailbox held standing PACS access to a trust's imaging archive.

Now:

  • imaging-api creates the XNAT user with a throwaway random password that is never disclosed, mints a single-use XNAT alias token on the user's behalf (the flipServiceAccount already holds the Administrator role this needs), and returns a host-less …/XDATScreen_UpdateUser.vm?a=…&s=… path.
  • the hub emails that path via the new flip-xnat-invite SES template (renamed from flip-xnat-credentials), with a note that the link only works from inside the trust's XNAT network — XNAT is not reachable over the public internet. No standing credential is ever transmitted.
  • Retest passes: git grep "password=decrypted" -- 'flip-api/**/*.py'0 hits.

The account is created with a password (not passwordless) on purpose: XNAT's password-change path raises on a user that has no existing password. Existing users added to a further project still receive the existing added-to-project notification.

XNAT enclave branding

configure-xnat.sh now sets the login-page site description to "Welcome to FLIP's XNAT at <trust>" (from TRUST_NAME, passed through to the xnat-web container; XNAT_SITE_DESCRIPTION overrides) and points siteLogoPath at a FLIP logo baked into the XNAT webapp image.

Testing

  • imaging-api: 276 passed · flip-api unit: 1484 passed · SES template validator: 5/5
  • ruff + mypy clean on changed files; terraform fmt clean
  • Verified live on the dev GSTT XNAT: invite token authenticates the new user and shows a set-password form; branded login page renders the FLIP logo + welcome line.

Deploy notes

  • Ordering: terraform apply the SES module so the flip-xnat-invite template exists before the hub is redeployed, otherwise send_email fails on a missing template.
  • Site description + logo land on the next XNAT image rebuild + stack redeploy (they are applied by configure-xnat.sh on fresh bring-up).

FLIP-PT-079: the hub decrypted the XNAT account password and emailed it in
cleartext via SES, so anyone able to read the mailbox held standing PACS
access to a trust's imaging archive.

Trust-side, imaging-api now creates the XNAT user with a throwaway random
password that is never disclosed, mints a single-use XNAT alias token, and
returns a host-less "set your own password" path. The hub emails that path
(new flip-xnat-invite SES template, renamed from flip-xnat-credentials) with
a note that the link only works from inside the trust's XNAT network. The
decrypt-and-email-password path is removed, so no standing credential is ever
transmitted. Retest `git grep "password=decrypted"` returns zero.

The account is created with a password (not passwordless) on purpose: XNAT's
password-change path raises on a user that has no existing password. Users who
already have an XNAT account and are added to a further project continue to
receive the existing added-to-project notification.

Signed-off-by: at24_bioeng625-pc <alexandre.triay_bagur@kcl.ac.uk>
… logo

The mocked XNAT at each trust shipped with the stock XNAT logo and the default
"Welcome to XNAT..." placeholder description, so a user reaching it over the
enclave could not tell which trust's XNAT they were on.

configure-xnat.sh now sets the site description to "Welcome to FLIP's XNAT at
<trust>" (from TRUST_NAME, passed through to the xnat-web container by the xnat
stack; XNAT_SITE_DESCRIPTION overrides the whole string) and points siteLogoPath
at a FLIP logo baked into the webapp image. The description JSON is built with jq
so a trust name containing an apostrophe stays valid.

Signed-off-by: at24_bioeng625-pc <alexandre.triay_bagur@kcl.ac.uk>
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

1 participant