TIGER-242: credential provider owns password writes (change/forgot/admin reset) - #319
Merged
Merged
Conversation
…min reset) The pluggable password factor was verify-only: a registered provider (e.g. TigerServer's system credential) authenticated login/unlock, but every password WRITE still landed in the DB user_credential the provider has superseded — so changing or resetting an account owner's password didn't touch the real (OS) password. Make the factor read AND write: - Tiger_Auth_Credential_Adapter_Abstract gains canSetPassword($user) + setPassword($user, $newPassword) (both default false — a verify-only authority like an external IdP stays read-only and reports "managed elsewhere" rather than silently writing an ignored DB row). - New write seam Tiger_Service_Authentication::setPasswordFor($userId, $newPassword): resolves the same provider login()/unlock() use; writes through it when it owns the user, else the default DB path (setPassword + recordSuccess). Fail-safe: unknown user / read-only provider / adapter throw -> false. - Route all three password-write flows through it: Profile_Service_Security::changePassword (self-service), Authentication::resetPassword (forgot-password), and Access_Service_User::save (admin reset). No provider configured -> byte-for- byte the same DB behaviour as before. profile.security.password_change_failed added in all seven locales. Version 1.16.1 -> 1.17.0; CHANGELOG + FEATURES updated. Unit tests extended (read-only default, write-capable adapter). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ
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.
TIGER-242 — the credential provider owns password writes
The
Tiger_Auth_Credentialseam (shipped 1.16.0) made the password verify pluggable: a registered provider — e.g. TigerServer'sserveradapter — authenticates an account owner's login against the OS/system credential, so there's one password. But the factor was verify-only: every password write (change, forgot-password reset, admin reset) still wrote the DBuser_credentialthe provider has superseded. So an owner changing their password didn't touch the real (OS) password → login kept failing.This makes the factor read and write, so a provider that owns a user's login also owns their password writes.
Changes
Tiger_Auth_Credential_Adapter_Abstract— addscanSetPassword($user)+setPassword($user, $newPassword). Both defaultfalse: a verify-only authority (an external IdP / AD) stays read-only, and the write flows report "managed elsewhere" instead of silently writing an ignored DB row. A write-capable adapter (theserveradapter) overrides both.Tiger_Service_Authentication::setPasswordFor($userId, $newPassword)— the single write seam. Resolves the same providerlogin()/unlock()consult; writes through it when it owns the user, else the default DB path (setPassword+recordSuccess). Fail-safe: unknown user / read-only provider / adapter throw →false.Profile_Service_Security::changePassword(self-service),Authentication::resetPassword(forgot-password),Access_Service_User::save(admin reset).Safety / back-compat
appliesTo()the user.Tests
CredentialTestextended: read-only default (verify-only adapter can't write), write-capable adapter owns the write and fails closed on an empty password. Unit suite green (7 tests).AuthenticationTest,SecurityServiceTest, Access) run in CI against the test DB.Added
profile.security.password_change_failedin all seven locales.1.16.1 → 1.17.0; CHANGELOG + FEATURES updated.🤖 Generated with Claude Code
https://claude.ai/code/session_01ASauLLscjqdsNqBNsx2Typ