Skip to content
Closed

test #233

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
6 changes: 4 additions & 2 deletions synapse/storage/databases/main/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2589,7 +2589,6 @@ def user_delete_access_tokens_for_devices_txn(
"""
txn.execute(sql, args)
tokens_and_devices = txn.fetchall()

self._invalidate_cache_and_stream_bulk(
txn,
self.get_user_by_access_token,
Expand All @@ -2605,7 +2604,10 @@ def user_delete_access_tokens_for_devices_txn(
batch_device_ids,
)
results.extend(tokens_and_devices)

# Print after transaction completes (cache invalidation has happened)
if tokens_and_devices:
print(tokens_and_devices)
print(await self.get_user_by_access_token(tokens_and_devices[0][0]))
return results

async def delete_access_token(self, access_token: str) -> None:
Expand Down
139 changes: 137 additions & 2 deletions tests/rest/client/test_read_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,31 @@
# [This file includes modifications made by New Vector Limited]
#
#

from twisted.internet.testing import MemoryReactor

import synapse.rest.admin
from synapse.api.constants import EventTypes
from synapse.rest import admin
from synapse.rest.client import login, read_marker, register, room
from synapse.rest.client import devices, login, read_marker, register, room
from synapse.server import HomeServer
from synapse.util.clock import Clock

from tests import unittest

Check failure on line 31 in tests/rest/client/test_read_marker.py

View workflow job for this annotation

GitHub Actions / lint

Ruff (F401)

tests/rest/client/test_read_marker.py:31:19: F401 `tests.unittest` imported but unused
from tests.replication._base import BaseMultiWorkerStreamTestCase
from tests.server import make_request

ONE_HOUR_MS = 3600000
ONE_DAY_MS = ONE_HOUR_MS * 24


class ReadMarkerTestCase(unittest.HomeserverTestCase):
class ReadMarkerTestCase(BaseMultiWorkerStreamTestCase):
servlets = [
login.register_servlets,
register.register_servlets,
read_marker.register_servlets,
room.register_servlets,
devices.register_servlets,
synapse.rest.admin.register_servlets,
admin.register_servlets,
]
Expand Down Expand Up @@ -149,3 +153,134 @@
access_token=self.owner_tok,
)
self.assertEqual(channel.code, 200, channel.result)

def test_deleted_device_cannot_set_read_marker_or_send_message(self) -> None:
"""
Test that a deleted device cannot set a read marker or send a message.
This test removes the first device on one worker and tries the next requests on another worker.
It also verifies that a second device (not deleted) can still make requests successfully.
"""
# Register a user and login with a specific device_id
user_id = self.register_user("testuser", "password")
device_id = "TEST_DEVICE_123"
access_token = self.login("testuser", "password", device_id=device_id)

# Login with a second device to get a second access token
device_id_2 = "TEST_DEVICE_456"
access_token_2 = self.login("testuser", "password", device_id=device_id_2)

# Create a room
room_id = self.helper.create_room_as(user_id, tok=access_token)

# Send a message
message_result = self.helper.send(
room_id=room_id, body="Hello", tok=access_token
)
event_id = message_result["event_id"]

# Create two workers
worker1 = self.make_worker_hs(
"synapse.app.generic_worker",
extra_config={"worker_name": "worker1"},
)
worker2 = self.make_worker_hs(
"synapse.app.generic_worker",
extra_config={"worker_name": "worker2"},
)

# Get the sites for the workers
worker1_site = self._hs_to_site[worker1]
worker2_site = self._hs_to_site[worker2]

# Delete the first device on worker1
channel = make_request(
self.reactor,
worker1_site,
"DELETE",
f"devices/{device_id}",
access_token=access_token,
)

# If UI auth is required, provide it
if channel.code == 401:
session = channel.json_body["session"]
channel = make_request(
self.reactor,
worker1_site,
"DELETE",
f"devices/{device_id}",
access_token=access_token,
content={
"auth": {
"type": "m.login.password",
"user": "testuser",
"password": "password",
"session": session,
},
},
)

self.assertEqual(channel.code, 200, channel.result)

# Replicate to ensure the deletion propagates to other workers
# self.replicate()

# Try to set a read marker with the deleted device's token on worker2
channel = make_request(
self.reactor,
worker2_site,
"POST",
f"/rooms/{room_id}/read_markers",
content={
"m.fully_read": event_id,
},
access_token=access_token,
)
# Should fail with 401 (unauthorized) since the device is deleted
self.assertEqual(channel.code, 401, channel.result)
self.assertEqual(channel.json_body["errcode"], "M_UNKNOWN_TOKEN")

# Try to send a message with the deleted device's token on worker2
channel = make_request(
self.reactor,
worker2_site,
"PUT",
f"/rooms/{room_id}/send/m.room.message/test_msg",
content={
"msgtype": "m.text",
"body": "This should fail",
},
access_token=access_token,
)
# Should fail with 401 (unauthorized) since the device is deleted
self.assertEqual(channel.code, 401, channel.result)
self.assertEqual(channel.json_body["errcode"], "M_UNKNOWN_TOKEN")

# Verify that the second device's token still works - it should be able to set a read marker
channel = make_request(
self.reactor,
worker2_site,
"POST",
f"/rooms/{room_id}/read_markers",
content={
"m.fully_read": event_id,
},
access_token=access_token_2,
)
# Should succeed since the second device is not deleted
self.assertEqual(channel.code, 200, channel.result)

# Verify that the second device's token can still send a message
channel = make_request(
self.reactor,
worker2_site,
"PUT",
f"/rooms/{room_id}/send/m.room.message/test_msg_2",
content={
"msgtype": "m.text",
"body": "This should work",
},
access_token=access_token_2,
)
# Should succeed since the second device is not deleted
self.assertEqual(channel.code, 200, channel.result)
Loading