Skip to content

Commit

Permalink
fix: Added permissions validation context to api error (#858)
Browse files Browse the repository at this point in the history
  • Loading branch information
josebui authored Oct 10, 2023
1 parent 89d052a commit 44f44cb
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 30 deletions.
26 changes: 17 additions & 9 deletions terraso_backend/apps/graphql/schema/story_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see https://www.gnu.org/licenses/.

from datetime import datetime

import django_filters
import graphene
import rules
Expand All @@ -37,12 +39,7 @@
from apps.story_map.notifications import send_memberships_invite_email
from apps.story_map.services import story_map_media_upload_service

from .commons import (
BaseAuthenticatedMutation,
BaseDeleteMutation,
BaseUnauthenticatedMutation,
TerrasoConnection,
)
from .commons import BaseAuthenticatedMutation, BaseDeleteMutation, TerrasoConnection
from .constants import MutationTypes

logger = structlog.get_logger(__name__)
Expand Down Expand Up @@ -290,7 +287,7 @@ def validate(context):
return cls(memberships=[membership["membership"] for membership in memberships])


class StoryMapMembershipApproveTokenMutation(BaseUnauthenticatedMutation):
class StoryMapMembershipApproveTokenMutation(BaseAuthenticatedMutation):
model_class = Membership
membership = graphene.Field(CollaborationMembershipNode)
story_map = graphene.Field(StoryMapNode)
Expand Down Expand Up @@ -350,8 +347,19 @@ def mutate_and_get_payload(cls, root, info, **kwargs):
"Attempt to approve a Membership, but user has no permission",
extra=kwargs,
)
raise GraphQLNotAllowedException(
model_name=Membership.__name__, operation=MutationTypes.UPDATE
error = GraphQLNotAllowedException(
model_name=Membership.__name__,
operation=MutationTypes.UPDATE,
message="permissions_validation",
)
return cls(
errors=[{"message": str(error)}],
story_map=StoryMap(
id="",
title=story_map.title,
created_at=datetime.now(),
updated_at=datetime.now(),
),
)

try:
Expand Down
15 changes: 3 additions & 12 deletions terraso_backend/apps/story_map/permission_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,12 @@ def allowed_to_approve_story_map_membership(user, obj):
return is_user_membership


# This rule is used to check if the user is allowed to approve a membership
# with a token. This is used when the user is not logged in or when the user
# is logged in but the membership is associated with the user.
@rules.predicate
def allowed_to_approve_story_map_membership_with_token(user, obj):
membership = obj.get("membership")
request_user = user

if membership.pending_email is not None:
return request_user.is_anonymous

if request_user.is_anonymous or request_user.id == membership.user.id:
return True

return False
if not membership.user:
return False
return user.id == membership.user.id


@rules.predicate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,8 @@ def test_story_map_approve_membership_with_token_for_registered_user(
def test_story_map_approve_membership_with_token_for_unregistered_user(
client_query_no_token,
story_map_user_memberships_not_registered_approve_tokens,
story_map_user_memberships_not_registered,
):
token = story_map_user_memberships_not_registered_approve_tokens[0]
membership = story_map_user_memberships_not_registered[0]

response = client_query_no_token(
"""
Expand All @@ -454,16 +452,14 @@ def test_story_map_approve_membership_with_token_for_unregistered_user(
)
json_response = response.json()

assert json_response["data"]["approveStoryMapMembershipToken"]["errors"] is None

response_membership = json_response["data"]["approveStoryMapMembershipToken"]["membership"]

assert response_membership["id"] == str(membership.id)
assert response_membership["membershipStatus"] == "APPROVED"
assert "errors" in json_response["data"]["approveStoryMapMembershipToken"]
error_result = json_response["data"]["approveStoryMapMembershipToken"]["errors"][0]["message"]
json_error = json.loads(error_result)
assert json_error[0]["code"] == "unauthorized"


def test_story_map_approve_membership_with_token_for_registered_user_fails_due_user_mismatch(
client_query, story_map_user_memberships_approve_tokens
client_query, story_map_user_memberships_approve_tokens, story_maps
):
token = story_map_user_memberships_approve_tokens[1]

Expand All @@ -473,6 +469,12 @@ def test_story_map_approve_membership_with_token_for_registered_user_fails_due_u
$input: StoryMapMembershipApproveTokenMutationInput!
){
approveStoryMapMembershipToken(input: $input) {
storyMap {
title
id
createdAt
updatedAt
}
membership {
id
membershipStatus
Expand All @@ -493,3 +495,8 @@ def test_story_map_approve_membership_with_token_for_registered_user_fails_due_u
error_result = json_response["data"]["approveStoryMapMembershipToken"]["errors"][0]["message"]
json_error = json.loads(error_result)
assert json_error[0]["code"] == "update_not_allowed"
assert (
json_response["data"]["approveStoryMapMembershipToken"]["storyMap"]["title"]
== story_maps[0].title
)
assert json_response["data"]["approveStoryMapMembershipToken"]["storyMap"]["id"] == ""

0 comments on commit 44f44cb

Please sign in to comment.