-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pass the right contexts to add_member() and edit_member()
Problem ------- `group_membership_api_factory()` is the context factory for all views that use the `"api.group_member"` route: * `remove_member()` (`request_method="DELETE"`) * `add_member()` (`request_method="POST"`) * `edit_member()` (`request_method="PATCH"`) * Add in #9197 also `get_member()` (`request_method="GET"`) `group_membership_api_factory()` returns a `GroupMembershipContext` object but: * `GroupMembershipContext` isn't the right context for `edit_member()`: it lacks the `context.new_roles` attribute for the new roles that the request wants to change `context.membership.roles` to. * `GroupMembershipContext` isn't the right context for `add_member()`: it has an inappropriate `context.membership` attribute (when adding a new membership there shouldn't be an existing membership in the context) and it lacks the `context.new_roles` attribute for the roles that the request wants to create a membership with. The context for the `edit_member()` view should be an `EditGroupMembershipContext` object, and for `add_member()` it should be an `AddGroupMembershipContext`. As a result the `edit_member()` view has to create its own context object to pass to `request.has_permission()`: def edit_member(context: GroupMembershipContext, request): appstruct = EditGroupMembershipAPISchema().validate(json_payload(request)) new_roles = appstruct["roles"] if not request.has_permission( Permission.Group.MEMBER_EDIT, EditGroupMembershipContext( context.group, context.user, context.membership, new_roles ), ): raise HTTPNotFound() When a future PR enables users (not just auth clients) to call the add-membership API the `add_member()` view will have to do something similar: constructing its own `AddGroupMembershipContext` object and passing it to `request.has_permission()`. This means there are two different context objects in play for the `edit_member()` and `add_member()` views: the `context` that is passed to the view is a `GroupMembershipContext`, but the `context` that is passed to `request.has_permission()` is an `EditGroupMembershipContext` or `AddGroupMembershipContext` constructed by the view itself. Solution ------- This commit changes `group_membership_api_factory()` to return a `GroupMembershipContext` for `GET` and `DELETE` requests but return an `EditGroupMembershipContext` for `PATCH` requests and an `AddGroupMembershipContext` for `POST`s. It's not possible for `group_membership_api_factory()` to set the context's `new_roles` attribute: the value for `new_roles` isn't available until later in the request processing cycle after the view has parsed and validated the request's JSON body. So the factory returns `context` objects with `context.new_roles=None` and the `edit_member()` view has to set `new_roles` before calling `has_permission()`: appstruct = EditGroupMembershipAPISchema().validate(json_payload(request)) context.new_roles = appstruct["roles"] if not request.has_permission(Permission.Group.MEMBER_EDIT, context): raise HTTPNotFound() In future the `add_member()` view will have to do the same. So this is still a little weird, but I think it's better than having two different context objects for a single request.
- Loading branch information
Showing
7 changed files
with
142 additions
and
32 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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