fix(api): report an authorization failure as 403, not 409 - #460
Open
kneckinator wants to merge 1 commit into
Open
fix(api): report an authorization failure as 403, not 409#460kneckinator wants to merge 1 commit into
kneckinator wants to merge 1 commit into
Conversation
AccessError subclasses UserError in Odoo, so the change-request state transitions — $submit, $approve, $apply and $reset — which caught UserError and returned 409 Conflict reported permission failures as conflicts. The client is told to resolve a conflict it cannot see, and one that retries on 409 (reasonable for a genuine conflict, which may clear) loops on a permission error that never will. It is most visible on $apply now that applying requires the change-request manager role: the endpoint's own scope check already returns 403, so the same endpoint reported two authorization failures with different statuses. The mapping lives in one helper rather than a fifth copy of the same except block, and a test fails if a handler goes back to a hard-coded status — this is exactly the bug that returns when the next endpoint is copy-pasted. ValidationError has the same shape (it also subclasses UserError, so a validation failure reports 409 where create() uses 422). Current behaviour is pinned by a test with a note rather than changed, being a separate API-contract decision.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 19.0 #460 +/- ##
=======================================
Coverage 76.28% 76.28%
=======================================
Files 654 654
Lines 44035 44039 +4
=======================================
+ Hits 33592 33596 +4
Misses 10443 10443
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
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.
An authorization failure on a change-request state transition is reported as
409 Conflictinstead of403 Forbidden.The bug
AccessErrorsubclassesUserErrorin Odoo (odoo/exceptions.py:77). Four endpoints inspp_api_v2_change_request/routers/change_request.py—$submit,$approve,$applyand$reset— did this:so any
AccessError— from a record rule, or from an authorization guard — surfaced as a conflict. That is wrong twice over:Why it matters now
$applyrequires the change-request manager role as of the batch-2 work (#422, #365). That guard raisesAccessError, so the documented operator instruction — "Deployments applying CRs via API must grant that role" — currently manifests as a 409, which reads as retryable rather than as "you lack permission".The endpoint's own client-scope check already returns 403, so today the same endpoint reports two authorization failures with two different statuses.
The fix
The mapping moves into
_status_for_odoo_error(), and each handler calls it — one line per site, rather than a fifth copy of the same block. All four endpoints are corrected, not just$apply: any of them can raiseAccessErrorfrom a record rule, and the change-request detail models gained record rules in #261.Tests
Five, including two beyond the obvious:
test_access_error_is_not_shadowed_by_its_base_classassertsAccessErroris aUserErrorand that the two still map differently, encoding the root cause rather than the symptom.test_every_state_transition_handler_uses_the_mappinginspects the router source and fails if any handler reverts to a hard-coded status — this is precisely the bug that comes back when the next endpoint is copy-pasted.Full
spp_api_v2_change_requestsuite: 85 tests, 0 failures.Noted, not changed
ValidationErroralso subclassesUserError, so a validation failure on these endpoints reports 409 wherecreate()uses 422 for the same condition. Current behaviour is pinned by a test with a note; changing it is a separate API-contract decision.Merge order
Independent — no other open PR touches
spp_api_v2_change_request.19.0.2.0.1 → 19.0.2.0.2. Worth landing alongside #422, since that PR's release notes describe the manager requirement whose error this corrects.