Profile: only edit fields Dex reads back
The Dex LDAP connector publishes uid, cn and mail as claims, so the profile page now offers just Name (cn), the verified email change and the password. The photo endpoint, SSH keys, addresses, phones and other extended attributes are no longer read or written; existing LDAP values are left untouched. Apache's profile upload limit drops back to the 256 KiB used by other member routes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -378,59 +378,38 @@ separate coordinated change, not an automatic part of this release.
|
||||
### Self-service account profile
|
||||
|
||||
Signed-in members can choose **Edit profile** from their membership page.
|
||||
Deploy the new membership image, apply migration `0005_profile_email_change`,
|
||||
and deploy the updated static CSS/proxy configuration. No new public settings
|
||||
or credentials are required. Login remains Dex-only: the profile editor reads
|
||||
LDAP **only when opened**, because the configured Dex LDAP connector exposes
|
||||
username/email/name/groups, not arbitrary LDAP attributes. Cached OIDC claims
|
||||
are neither a complete nor a current editable profile. Do not map the gamer tag
|
||||
to `preferred_username` or change `idAttr` to expose it.
|
||||
Login is Dex-only, and the profile editor offers **only the values the Dex LDAP
|
||||
connector reads back into ID-token claims**, so what a member edits is exactly
|
||||
what downstream services receive. The editor reads LDAP **only when opened**;
|
||||
cached OIDC claims are not treated as a current profile.
|
||||
|
||||
| Profile label | LDAP attribute |
|
||||
| --- | --- |
|
||||
| About you | `description` |
|
||||
| Gamer tag (one value) | `displayName` |
|
||||
| Email address (verified separately) | `mail` |
|
||||
| First name / Last name | `givenName` / `sn` |
|
||||
| Profile photo | `jpegPhoto` |
|
||||
| City/town / State/province | `l` / `st` |
|
||||
| Websites | `labeledURI` |
|
||||
| Mobile numbers / Phone numbers | `mobile` / `telephoneNumber` |
|
||||
| Organizations / Job titles | `o` / `title` |
|
||||
| Postal addresses / Postal codes | `postalAddress` / `postalCode` |
|
||||
| Street addresses / Room numbers | `street` / `roomNumber` |
|
||||
| SSH public keys | `sshPublicKey` |
|
||||
| Password | RFC 3062 Password Modify (never read back) |
|
||||
| Profile label | LDAP attribute | Dex claim |
|
||||
| --- | --- | --- |
|
||||
| Username (read-only) | `uid` | `preferred_username` |
|
||||
| Name (one value) | `cn` (connector `nameAttr`) | `name` |
|
||||
| Email address (verified separately) | `mail` | `email` |
|
||||
| Password | RFC 3062 Password Modify (never read back) | — |
|
||||
|
||||
The form preserves existing multi-value attributes. Enter one value per line;
|
||||
separate multiline postal addresses with a blank line. Blank optional fields
|
||||
are removed on save; `sn` remains required by the directory schema. JPEGs are
|
||||
limited to 1 MiB and 4096 pixels per side/16 million pixels, resized to fit 512
|
||||
pixels and reencoded without metadata. Existing photos are sanitized again
|
||||
before private, authenticated delivery. No arbitrary URLs are fetched. Supported
|
||||
SSH keys are Ed25519, RSA >=2048 bits and ECDSA NIST P-256/P-384/P-521; private
|
||||
keys, authorized_keys options and malformed values are rejected.
|
||||
Other directory attributes (photos, SSH keys, addresses, `displayName`, etc.)
|
||||
are neither shown nor modified, so existing values are left in place. If the
|
||||
connector's `nameAttr` is changed, change `profiles.TEXT_ATTRIBUTES` to match.
|
||||
Saving the name replaces every `cn` value with the single entered value; Dex
|
||||
already uses only the first. Account DNs must not use `cn` as their RDN.
|
||||
|
||||
**Directory prerequisites:**
|
||||
|
||||
- The service account needs read/search access to the profile attributes above,
|
||||
plus `uid`, `entryUUID`, `objectClass` and `modifyTimestamp`, across the
|
||||
- The service account needs read/search access to `cn`, `mail`, `uid`,
|
||||
`entryUUID` and `modifyTimestamp`, across the
|
||||
intended account search tree. It never needs read access to `userPassword`.
|
||||
Accounts are pinned to immutable UUIDs; missing/deleted entries do not fall
|
||||
back to a reused username. LDAP unavailability disables editing rather than
|
||||
presenting an empty form that could erase values.
|
||||
- Every write binds with the member's **current LDAP password** and checks that
|
||||
entry's UUID again. Configure directory **self-write ACLs** only for these
|
||||
profile attributes and self Password Modify; do not grant writes to `uid`,
|
||||
entry's UUID again. Configure directory **self-write ACLs** only for `cn`,
|
||||
`mail` and self Password Modify; do not grant writes to `uid`,
|
||||
`entryUUID`, account DNs, POSIX IDs, group membership or administrative fields.
|
||||
This supports existing Dex users outside the website registration OU without
|
||||
granting the membership service unrestricted directory write permissions.
|
||||
- Install the `ldapPublicKey` auxiliary schema before SSH editing. When a user
|
||||
supplies keys and the class is absent, the application adds **only** the fixed
|
||||
`ldapPublicKey` class in the same modify. Either pre-add that class to editable
|
||||
accounts or permit precisely that self-add with value-scoped `objectClass`
|
||||
ACLs. Never grant arbitrary self-write to `objectClass`. No schema/ACL changes
|
||||
are automatically applied by the website or OpenLDAP role.
|
||||
- OpenLDAP must support critical RFC 4528 assertion controls. Profile/email
|
||||
writes assert UUID and last-modified time, and profile forms carry a signed,
|
||||
one-hour revision to reject stale edits. A server rejecting the critical
|
||||
@@ -462,15 +441,13 @@ automatically revoked—use each service's session controls when necessary.
|
||||
All writes are CSRF-protected and rate-limited per account/IP. Passwords and
|
||||
profile form bodies must never be logged by ingress/APM/LDAP debug logging.
|
||||
Profile data can be shared by directory-consuming services: the page is private,
|
||||
but it does not make phone/address/SSH fields private in the directory. Enforce
|
||||
but it does not make other directory attributes private. Enforce
|
||||
directory read ACLs and tell users what other services can access. TLS defaults
|
||||
are unchanged; the existing explicit plaintext opt-in also exposes profile
|
||||
passwords/data and should not be used on untrusted networks.
|
||||
|
||||
The supplied Kubernetes ingress accepts up to 2 MiB; Apache allows that limit
|
||||
only under `/members/profile/` and retains 256 KiB for other member routes.
|
||||
Mirror the limits at any additional edge proxy. Oversized or invalid uploads
|
||||
must be rejected before reaching image processing.
|
||||
Apache limits all member routes, including the profile, to 256 KiB request
|
||||
bodies; mirror that limit at any additional edge proxy.
|
||||
|
||||
### Database ProgrammingError during callback
|
||||
|
||||
|
||||
Reference in New Issue
Block a user