domain: revoke_access_token returns Ok for a foreign/nonexistent token while the UI reports success #62
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
rosa/vernier#62
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found during a code review of the
domaincrate.Location:
crates/domain/src/services.rs:888(revoke_access_token)Severity: Correctness — inconsistent ownership guard
Problem
revoke_access_tokenreturnsOk(())when the token is absent or belongs to another user, unlike sibling owner-gated mutations (delete_post,update_post) which return NotFound/Unauthorized. The caller flashes a success message regardless, so a foreign or nonexistent id reports success while any such token stays live.Failure scenario
A handler bug or forged id passes the wrong
AccessTokenId; the user is told the token was revoked while it remains active, and there is no error variant to surface or assert against.Suggested fix
Add a
RevokeTokenError { NotFound, Unauthorized, Unknown }and return it, matching the other owner-gated mutations.Verified during triage by code inspection: the service silently returns
Ok(())when the token id doesn't exist or belongs to another user, and the account-page handler flashes "Access token revoked." unconditionally. Sibling owner-gated mutations (post edit/delete) return dedicatedNotFound/Unauthorizederrors.Agent Brief
Category: bug
Summary:
revoke_access_tokenmust report not-found / not-yours instead of silently succeeding, and the UI must stop claiming success when nothing was revokedCurrent behavior:
revoke_access_tokenlooks up the token, and only deletes it when it exists and belongs to the calling user — but returnsOk(())in every case. The web handler then flashes a success message regardless. A nonexistent or foreign token id reports "Access token revoked." while any such token stays live. There is no error variant to surface or write assertions against.Desired behavior:
Revocation follows the same owner-gated contract as the post mutations: a dedicated error enum distinguishing not-found, not-owned, and unknown failures. The web handler surfaces those as the app's usual not-found / forbidden responses instead of the success flash. Revoking one's own existing token behaves exactly as today (deleted + success flash).
Key interfaces:
NotFound,Unauthorized, andUnknownvariants, following the naming and shape of the existing owner-gated mutation errors (e.g. the post delete error).revoke_access_tokenreturns it instead ofanyhow::Error.Frommapping into the web error type consistent with how the sibling errors map (not-found → 404-style, unauthorized → forbidden-style).Acceptance criteria:
cimise task passes.Out of scope: