Skip to content

Commit

Permalink
Add unit tests for the MSC4190 behaviours
Browse files Browse the repository at this point in the history
  • Loading branch information
sandhose committed Nov 26, 2024
1 parent aa8842d commit 5f4235d
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 4 deletions.
13 changes: 11 additions & 2 deletions tests/handlers/test_appservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,12 +1165,21 @@ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
self.hs.get_datastores().main.services_cache = [self._service]

# Register some appservice users
self._sender_user, self._sender_device = self.register_appservice_user(
user_id, device_id = self.register_appservice_user(
"as.sender", self._service_token
)
self._namespaced_user, self._namespaced_device = self.register_appservice_user(
# With MSC4190 enabled, we may not have a device out of the
# registration, but we don't have it enabled in this test
assert device_id is not None
self._sender_user = user_id
self._sender_device = device_id

user_id, device_id = self.register_appservice_user(
"_as_user1", self._service_token
)
assert device_id is not None
self._namespaced_user = user_id
self._namespaced_device = device_id

# Register a real user as well.
self._real_user = self.register_user("real.user", "meow")
Expand Down
177 changes: 177 additions & 0 deletions tests/rest/client/test_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from twisted.test.proto_helpers import MemoryReactor

from synapse.api.errors import NotFoundError
from synapse.appservice import ApplicationService
from synapse.rest import admin, devices, sync
from synapse.rest.client import keys, login, register
from synapse.server import HomeServer
Expand Down Expand Up @@ -455,3 +456,179 @@ def test_msc3814_dehydrated_device_delete_works(self) -> None:
token,
)
self.assertEqual(channel.json_body["device_keys"], {"@mikey:test": {}})


class MSC4190AppserviceDevicesTestCase(unittest.HomeserverTestCase):
servlets = [
register.register_servlets,
devices.register_servlets,
]

def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
self.hs = self.setup_test_homeserver()

self.msc4190_service = ApplicationService(
id="msc4190",
token="some_token",
hs_token="some_token",
sender="@as:example.com",
namespaces={
ApplicationService.NS_USERS: [{"regex": "@.*", "exclusive": False}]
},
msc4190_device_management=True,
)
self.regular_service = ApplicationService(
id="regular",
token="other_token",
hs_token="other_token",
sender="@as2:example.com",
namespaces={
ApplicationService.NS_USERS: [{"regex": "@.*", "exclusive": False}]
},
msc4190_device_management=False,
)
self.hs.get_datastores().main.services_cache.append(self.msc4190_service)
self.hs.get_datastores().main.services_cache.append(self.regular_service)
return self.hs

def test_PUT_device(self) -> None:
self.register_appservice_user("alice", self.msc4190_service.token)
self.register_appservice_user("bob", self.regular_service.token)

channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(channel.json_body, {"devices": []})

channel = self.make_request(
"PUT",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@alice:test",
content={"display_name": "Alice's device"},
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 201, channel.json_body)

channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(len(channel.json_body["devices"]), 1)
self.assertEqual(channel.json_body["devices"][0]["device_id"], "AABBCCDD")

# Doing a second time should return a 200 instead of a 201
channel = self.make_request(
"PUT",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@alice:test",
content={"display_name": "Alice's device"},
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)

# On the regular service, that API sh
channel = self.make_request(
"PUT",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@bob:test",
content={"display_name": "Bob's device"},
access_token=self.regular_service.token,
)
self.assertEqual(channel.code, 404, channel.json_body)

def test_DELETE_device(self) -> None:
self.register_appservice_user("alice", self.msc4190_service.token)

# There should be no device
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(channel.json_body, {"devices": []})

# Create a device
channel = self.make_request(
"PUT",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@alice:test",
content={},
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 201, channel.json_body)

# There should be one device
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(len(channel.json_body["devices"]), 1)

# Delete the device
channel = self.make_request(
"DELETE",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)

# There should be no device again
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(channel.json_body, {"devices": []})

def test_POST_delete_devices(self) -> None:
self.register_appservice_user("alice", self.msc4190_service.token)

# There should be no device
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(channel.json_body, {"devices": []})

# Create a device
channel = self.make_request(
"PUT",
"/_matrix/client/v3/devices/AABBCCDD?user_id=@alice:test",
content={},
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 201, channel.json_body)

# There should be one device
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(len(channel.json_body["devices"]), 1)

# Delete the device with delete_devices
channel = self.make_request(
"POST",
"/_matrix/client/v3/delete_devices?user_id=@alice:test",
content={"devices": ["AABBCCDD"]},
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)

# There should be no device again
channel = self.make_request(
"GET",
"/_matrix/client/v3/devices?user_id=@alice:test",
access_token=self.msc4190_service.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
self.assertEqual(channel.json_body, {"devices": []})
28 changes: 28 additions & 0 deletions tests/rest/client/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,34 @@ def test_POST_appservice_registration_invalid(self) -> None:

self.assertEqual(channel.code, 401, msg=channel.result)

def test_POST_appservice_msc4190_enabled(self) -> None:
# With MSC4190 enabled, the registration should *not* return an access token
user_id = "@as_user_kermit:test"
as_token = "i_am_an_app_service"

appservice = ApplicationService(
as_token,
id="1234",
namespaces={"users": [{"regex": r"@as_user.*", "exclusive": True}]},
sender="@as:test",
msc4190_device_management=True,
)

self.hs.get_datastores().main.services_cache.append(appservice)
request_data = {
"username": "as_user_kermit",
"type": APP_SERVICE_REGISTRATION_TYPE,
}

channel = self.make_request(
b"POST", self.url + b"?access_token=i_am_an_app_service", request_data
)

self.assertEqual(channel.code, 200, msg=channel.result)
det_data = {"user_id": user_id, "home_server": self.hs.hostname}
self.assertLessEqual(det_data.items(), channel.json_body.items())
self.assertNotIn(channel.json_body, "access_token")

def test_POST_bad_password(self) -> None:
request_data = {"username": "kermit", "password": 666}
channel = self.make_request(b"POST", self.url, request_data)
Expand Down
4 changes: 2 additions & 2 deletions tests/unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ def register_appservice_user(
self,
username: str,
appservice_token: str,
) -> Tuple[str, str]:
) -> Tuple[str, Optional[str]]:
"""Register an appservice user as an application service.
Requires the client-facing registration API be registered.
Expand All @@ -805,7 +805,7 @@ def register_appservice_user(
access_token=appservice_token,
)
self.assertEqual(channel.code, 200, channel.json_body)
return channel.json_body["user_id"], channel.json_body["device_id"]
return channel.json_body["user_id"], channel.json_body.get("device_id")

def login(
self,
Expand Down

0 comments on commit 5f4235d

Please sign in to comment.