Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions backend/backend/graphene/mutations/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,15 @@ class Arguments:
def mutate(cls, root, info, token_id):
user = info.context.user
token = UserToken.objects.get(id=token_id)
org = token.user.organisation

if user_is_org_member(user.userId, org.id):
token.deleted_at = timezone.now()
token.save()
# Verify the token belongs to the requesting user
if token.user.user != user:
raise GraphQLError("You don't have permission to delete this token")

return DeleteUserTokenMutation(ok=True)
else:
raise GraphQLError("You don't have permission to perform this action")
token.deleted_at = timezone.now()
token.save()

return DeleteUserTokenMutation(ok=True)


class CreateServiceTokenMutation(graphene.Mutation):
Expand Down
Empty file.
52 changes: 52 additions & 0 deletions backend/tests/api/mutations/test_delete_user_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import pytest
from unittest.mock import MagicMock, patch
from graphql import GraphQLError


class TestDeleteUserTokenMutationOwnership:
"""Tests that DeleteUserTokenMutation enforces token ownership."""

@patch("backend.graphene.mutations.environment.UserToken")
def test_rejects_deletion_of_another_users_token(self, MockUserToken):
"""A user should not be able to delete another user's token."""
from backend.graphene.mutations.environment import DeleteUserTokenMutation

requesting_user = MagicMock()
requesting_user.userId = "user-A"

token_owner = MagicMock()
# token.user is an OrgMember, token.user.user is the actual User
mock_token = MagicMock()
mock_token.user.user = token_owner # Different user object

MockUserToken.objects.get.return_value = mock_token

mock_info = MagicMock()
mock_info.context.user = requesting_user

with pytest.raises(GraphQLError, match="You don't have permission to delete this token"):
DeleteUserTokenMutation.mutate(None, mock_info, "token-123")

# Token should not have been modified
mock_token.save.assert_not_called()

@patch("backend.graphene.mutations.environment.UserToken")
def test_allows_deletion_of_own_token(self, MockUserToken):
"""A user should be able to delete their own token."""
from backend.graphene.mutations.environment import DeleteUserTokenMutation

the_user = MagicMock()

mock_token = MagicMock()
mock_token.user.user = the_user # Same user object

MockUserToken.objects.get.return_value = mock_token

mock_info = MagicMock()
mock_info.context.user = the_user # Same user

result = DeleteUserTokenMutation.mutate(None, mock_info, "token-123")

assert result.ok is True
mock_token.save.assert_called_once()
assert mock_token.deleted_at is not None
Loading