Repository navigation
Add LDAP login provider, provider-linked account lifecycle, and a shared provider-customizable login form - #1155
devin-ai-integration[bot] wants to merge 123 commits into
Conversation
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
✅ Version Already UpdatedThis PR includes a manual version update to No automatic version bump needed. |
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
|
Browser-tested the login UI with a production build and the LDAPS OpenLDAP fixture:
Separately, 61eb14a fixes "Check existing accounts survive the upgrade". The step seeded accounts by starting |
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…d provider, login accessibility Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…tch provider group names case-insensitively Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…apart; log the groups each login reports Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…artup, log why each login was refused, reject non-PEM CA files Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ogins per account (AUTH_MAX_FAILED_LOGINS); key the service-account backoff without hashing the password Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…her provider enabled, optional-mode sign-up follows AUTH_LOCAL_ALLOW_SIGNUP Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ep group names exact - LDAP lookup(subject) and shared stillLinked(): every AUTH_RECHECK_MINUTES (default 15) group changes reach existing sessions and API tokens, and deleted/disabled/locked accounts lose access - Provider group names match exactly, including case, for every provider (reverts the shared case-insensitive match); docs say to copy the DN from the login log - syncGroups ignores duplicate memberships when two syncs race - LDAP e2e runs in order and uses its own recheck-team group Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ovider renames without renaming the MMGIS account Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…refuse local passwords on provider-linked accounts Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
- Per-form failed-login limits keyed by NFKC-normalized username; only 401s count; reset on relink - Relink names the provider username, pins the directory entry, runs in a transaction, ends sessions, replaces the local password, protects the last password SuperAdmin - Case-insensitive username collisions, concurrent first-login retry - LDAP group paging, duplicate-entry and size-limit diagnostics - Docs: exact group matching, rename guidance, limiter behavior; restore CRLF Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ocal logins per address Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…CA/password rotation Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…links, recheck AD expiry, show the account-type hint only after wrong passwords Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…he reported form, default relink to the provider username Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…the card instead of positioning it off the centered card Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…in the top bar and menu, 'Signed in with <provider>' in the menu, no hover title Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…e top-bar button Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…98-ldap-auth-provider Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com> # Conflicts: # configure/package.json # package.json
🤖 Version Auto-BumpedThe version has been automatically incremented to This commit was added to your PR branch. When you merge this PR, the new version will be included. If you want a different version, update |
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
… wording from plugin.json Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…of reporting no groups Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ping warning and server notes shown in place instead of a toast Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…does Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…embership-change warning, readable check errors with the provider's display name Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…ndler promises Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…sernames after CORS Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…rAdmin badge in plum Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
… root without trailing-slash slip Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
…e column, marked with their source Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
Co-Authored-By: tariq.k.soliman <tariqksoliman@gmail.com>
|



Purpose
ldapauth provider.Proposed Changes
LDAP provider (
plugins/core/auth/Ldap/, npm dependencyldaptsdeclared in itsplugin.json)LDAP_TLS_CAfor internal CAs. Startup refuses plainldap://unlessLDAP_ALLOW_INSECURE=true, which is for testing only.LDAP_BIND_DN,LDAP_USER_SEARCH_BASE/FILTER);LDAP_USER_DN_TEMPLATE).entryUUID, orobjectGUIDon AD. Changeable attributes are allowed, but startup warns about them.memberOfor a group search, which covers AD nested groups.LDAP_GROUP_NAME_ATTRIBUTE, and matched to MMGIS groups exactly.DOMAIN\name, are refused before their password is tried.LDAP_DISPLAY_NAME,LDAP_USERNAME_LABELandLDAP_LOGIN_HINT.Shared login forms
plugin.jsonfieldslogin_formandlogin_icon, aloginForm(env)hook, andproviders.loginForms()/providerLabel().GET /api/authalso returnsloginForms.localis now a form provider too.AUTH_PROVIDERS. The last choice is remembered.AUTH_LOCAL_LOGIN=admins, local accounts are offered only at Configure sign-in. A non-admin's correct local password now gets the same "Invalid username or password." as a wrong one, with the reason in the server log. Before, the message confirmed the password.Provider-linked accounts (shared, in
API/permissions/providers.js; any provider can use them)AUTH_PROVIDER_NEW_ACCOUNTS=false.AUTH_RECHECK_MINUTES(lookuphook).POST /api/accounts/allowRelink,/cancelRelink). An admin lets one provider sign-in, within 24 h, take over an existing account and keep everything it has.findSubject).plugin.jsonsets"relink": true. LDAP does; proxy doesn't.POST /api/accounts/recheckLinkedchecks every linked account now.auth_identities.username,last_login_atandsubject_setting, added at startup. Relink and not-found state is stored in the existingauth_metatable.Sign-in hardening
AUTH_MAX_FAILED_LOGINS), per address, and per directory entry.CORS_ORIGINSsites are still allowed.SITE_ACCESS=optional, visitor sign-up closes once another provider is enabled, so nobody can claim a directory user's username first.Configure > Users & Access
It also has Open the map and Sign out. Viewer grants are left out because they give no Configure access.
GET /api/access/me?grants=truealso returnsgrantsandprovider. Without the parameter, the response is unchanged.r[2],#7c1158) instead of pink. The account menu reuses the table badge styles, so role colors match everywhere.Plugins, tests and CI
"ci": { "script": "tests/ci.sh", "variants": [...] }inplugin.json. A genericplugin-ciworkflow job runs each declared script throughscripts/plugin-ci.jsand then that plugin's tests. LDAP (ldaps,starttls, against a real OpenLDAP) and proxy (network,secret) use it.@unittag (npm run test:plugins:unit). Each plugin's tests live in that plugin's folder. Core tests use a stand-in provider, so removing a provider plugin breaks no core test.ldapandproxyare replaced byplugin-ci. Any required-check settings that name the old jobs need updating.Settings and docs
[ADD] New settings:
AUTH_MAX_FAILED_LOGINS(5)AUTH_RECHECK_MINUTES(15)AUTH_PROVIDER_NEW_ACCOUNTS(true)LDAP_*settingsAll are in
sample.envanddocs/pages/Setup/ENVs/ENVs.md.[CHANGE] Changed settings:
AUTH_PROVIDERSaccepts"ldap".AUTH_LOCAL_ALLOW_SIGNUPandSETUP_CODEbehave as described under Fixes above.[ADD] Docs:
docs/pages/Setup/LDAP/LDAP.md, covering setup for OpenLDAP and AD, rollout, a one-account migration runbook, moving to a new directory, leavers, outages, rollback and troubleshooting.lookup/locate/findSubjecthooks and"relink": true.Issues
plugin.json).Testing
PLAYWRIGHT_TEST_UNIT_ONLY=true playwright test tests/unit: 1770 passed.npm run test:plugins:unit: 47 passed.scripts/plugin-ci.jsLDAPldapsagainst OpenLDAP: 24 passed, 2 skipped.scripts/plugin-ci.json the earlier plugin-CI commit (5f91c16):starttls: 24 passed, 2 skipped.network: 8 passed.secret: 8 passed.AUTH_LOCAL_LOGIN=admins, checked against a running server:test_userwith its correct password and with a wrong one both get "Invalid username or password.", andtest_adminsigns in.test_adminshows SuperAdmin.ldap_aliceshows Data Admin site-wide and Layer Editor on a mission through an LDAP group; a whole-mission grant merged with a layer grant shows no layer count. Sign out returns to/. Unit tests: 1771 passed.Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/408eb3c9ca61431cab68b9a361f23fdb
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/408eb3c9ca61431cab68b9a361f23fdb?variant=devin
Requested by: @tariqksoliman