Defect #44271
openOAuth token scopes ignored for issue edit, notes and delete
Description
When a request is authenticated with a Doorkeeper OAuth access token, several issue mutations are authorised from the resource owner's roles alone and never consult User#allowed_to?. Doorkeeper's oauth_scope filter therefore does not apply on those paths.
Effective permission is supposed to be:
Application scopes ∩ token scopes ∩ project roles
For the paths below, token scopes are decorative: if the user's role grants the permission, the API action succeeds even when the matching scope is absent from the access token.
Affected paths¶
All of these go through private Issue#user_tracker_permission?, which selects roles with has_permission? / tracker permission flags and does not call allowed_to?:
attributes_editable?(edit_issues/edit_own_issues) — attribute updates, bulk edit, attachment edit/deletenotes_addable?(add_issue_notes) — adding notesdeletable?(delete_issues) — destroying issuesattachments_addable?— attachments when edit or notes is allowed
Not affected (for contrast)¶
These go through User#allowed_to? and do honour oauth_scope:
- creating issues (
allowed_to?(:add_issues)) - copying issues (
allowed_to?(:copy_issues)) - viewing issues (
visible?→allowed_to?(:view_issues)) - wiki and other resources that use
allowed_to?
Environment¶
- Redmine 6.1.x
- OAuth / Doorkeeper enabled
- Reproduced via REST API (also visible through OAuth API clients such as MCP)
Steps to reproduce¶
- Create an OAuth application whose scopes include
view_issuesandadd_issue_notesbut notedit_issues(and optionally notdelete_issues). - Obtain an access token for a user who does have Edit issues (and Delete issues) on a project. Confirm token scopes via introspection or
oauth_access_tokens.scopes. - With that Bearer token:
PUT /issues/:id.jsonwith only an attribute change, e.g.{"issue":{"subject":"oauth-scope-repro"}}- optionally
DELETE /issues/:id.jsonifdelete_issueswas omitted from the token but present on the role
Expected¶
Attribute update (and delete, if tested) returns 403 because the token lacks edit_issues / delete_issues, even though the user's role would allow the action under session or API-key auth.
Actual¶
The mutation succeeds. By contrast, a wiki call without view_wiki_pages on the same token is correctly denied via allowed_to?.
Cause¶
Issue#user_tracker_permission? authorises from project roles and per-tracker permission flags only. It never invokes User#allowed_to?, so oauth_scope is never applied.
Notes¶
- Distinct from #44174 (API key exposure on My account under OAuth).
- Fix direction: route these checks through
allowed_to?(or otherwise intersect withuser.oauth_scope) while preserving tracker-scoped role behaviour.
No data to display