fix(members): Scope invite-request role updates to caller's allowed roles#115807
Merged
Conversation
…oles The PUT handler on the invite-request details endpoint validated the incoming role against roles.get_all() in the serializer context, while the adjacent approve path correctly used get_allowed_org_roles(request, organization). This left a Manager-level caller able to rewrite a pending invite request to a role they were not authorized to assign (e.g. owner); the escalated role would then be persisted by the following save() and could be approved by any Owner reviewing the queue. Align the role-update path with the approve path and with the equivalent PUT on organization_member_details. Add regression tests covering both `role` and `orgRole` field shapes. Co-Authored-By: Claude <noreply@anthropic.com>
…vite-request PUT Without `creating_org_invite=True`, `get_allowed_org_roles` short-circuits to an empty collection for any caller lacking the `member:admin` scope. The endpoint's permission class accepts `member:write` or `member:admin` for PUT, so a user auth token or org auth token scoped to `member:write` only could previously update an invite request but would now receive a 400 on every role update — a regression introduced by the previous commit. Mirror the POST handler on OrganizationMemberIndexEndpoint: pass `creating_org_invite=True`, and fall back to `[member]` for integration tokens that have no associated OrganizationMember. Add regression tests covering an internal integration token with `member:write`: it can update an invite to the member role and is still blocked from escalating to owner. Co-Authored-By: Claude <noreply@anthropic.com>
geoffg-sentry
approved these changes
May 19, 2026
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.
Align the PUT handler on
OrganizationInviteRequestDetailsEndpointwith the approve path on the same endpoint and with the equivalent PUT onorganization_member_details.Previously, the role-update path constructed
OrganizationMemberRequestSerializerwithallowed_roles=roles.get_all(), so any caller who passed themember:write/member:adminscope check on the endpoint could set the invite's role to anything in the role table — including roles they themselves could not assign. The approve branch one block down already usedget_allowed_org_roles(request, organization), so a Manager could not directly approve an owner invite, but they could rewrite a pending non-owner invite to owner and leave it for an Owner to approve from the request queue. The escalated role is persisted by the immediatemember.save(), so the gap is observable in isolation as well as via the approve chain.The fix is the one-line swap to
get_allowed_org_roles(request, organization)in the update-path serializer context. The approve-sidevalidate_invitationcheck is left as-is; it remains a correct second-stage gate on the approver's allowed roles.Tests:
test_manager_cannot_escalate_invite_role_to_ownerandtest_manager_cannot_escalate_invite_orgrole_to_ownerexercise both the deprecatedroleand currentorgRoleshapes. They fail againstmaster(200 + persisted owner role) and pass with the fix (400 + role unchanged).Fixes CORE-167