Add DISABLE_PASSWORD_LOGIN to hide local login when OIDC is configured - #240
Merged
alxlion merged 3 commits intoSep 11, 2026
Conversation
added 2 commits
August 16, 2026 09:33
Adds DISABLE_PASSWORD_LOGIN (default false). When set and OIDC is actually configured (OIDC_CLIENT_ID/OIDC_CLIENT_SECRET), the login page hides the email/password form, the "Forgot your password?" and "Create account" links, and both the login POST and registration POST controller actions refuse the request server-side (not just a hidden form -- the underlying routes are gated too) and send the user to /users/oidc instead. If OIDC is not configured, the flag is ignored (with a startup warning) rather than locking everyone out, including the seeded default admin. Admin bootstrap with this enabled: the seeded default admin (admin@claper.co) is created via a password login that will then be unusable. Log in once as that seeded admin (or any existing local admin) before enabling the flag, log in once via OIDC as the account that should become your real admin, promote that OIDC account to admin from the admin panel, and only then set DISABLE_PASSWORD_LOGIN=true. I didn't attempt to automate this step -- deciding which identity inherits admin rights isn't something a PR should assume on the maintainers' behalf. Also fixes an unrelated pre-existing gap in the same controller: POST /users/register had no ENABLE_ACCOUNT_CREATION check at all (only the GET /users/register that renders the form did), so registration was possible via a direct POST even with account creation "disabled" in the UI. Verified against a real dev instance (compose.dev.yml, isolated container, torn down after): with OIDC configured and the flag on, the password form and related links are gone from /users/log_in, a POST with valid password credentials redirects to /users/oidc instead of logging in, and GET /users/register redirects (302) instead of rendering the form. Fixes ClaperCo#233
:let must come before :if on <.form> per the project's HEEx formatter, and two lines exceeded the 98-column default.
Change runtime.exs to consider empty or whitespace-only OIDC credentials as not configured and update the warning text accordingly. Add runtime_config_test.exs to cover these cases, including empty secret files. Update user controller tests to exercise disable_password_login permutations and make session tests run synchronously. Also adjust Docker dev setup to run ecto.setup and map Postgres port in compose.dev.yml.
Contributor
|
Thanks for the contribution. I reviewed the implementation and pushed a follow-up commit to cover a few edge cases:
The feature now looks ready from my side. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#233 asks to disable the local email/password login and keep only OIDC, so systems that already have OIDC set up don't show a confusing second login path.
What this adds
DISABLE_PASSWORD_LOGIN(defaultfalse). When set and OIDC is actually configured (OIDC_CLIENT_ID/OIDC_CLIENT_SECRET), it:/users/oidc, and the registration route refuses it and redirects home with a flash messageAdmin bootstrap
You raised this yourself in the issue, and I didn't try to auto-solve it. Deciding which identity should inherit admin rights isn't something a PR should assume on your behalf. The sequence I'd document (also in the
.env.samplecomment I added):admin@claper.co(or any existing local admin)DISABLE_PASSWORD_LOGIN=trueUnrelated fix bundled in
While in
UserRegistrationController, I noticedPOST /users/registerhad noENABLE_ACCOUNT_CREATIONcheck at all, onlyGET /users/register(the form) did. So registration was possible via a direct POST even with account creation "disabled" in the UI. Fixed the same way, a sharedaccount_creation_allowed?/0gate on both actions. Happy to split this into its own PR if you'd rather review it separately, flagging it here so it doesn't look buried.Verification
Live-tested against a real running instance with OIDC configured and the flag on: password form and related links are gone from
/users/log_in, a POST with valid password credentials redirects to/users/oidcinstead of logging in, andGET /users/registerredirects (302) instead of rendering the form.Ran the real suite in an isolated dev container against this branch specifically (fresh checkout, not a mix of branches):
mix format --check-formattedclean,mix testpasses 339/339 (336 existing plus 3 new tests for the login-page and login-POST behavior).Fixes #233