Add query parameter ts to allow appservices set the origin_server_ts for state events. (#11866)

MSC3316 declares that both /rooms/{roomId}/send and /rooms/{roomId}/state
should accept a ts parameter for appservices. This change expands support
to /state and adds tests.
This commit is contained in:
lukasdenk 2022-10-03 14:30:45 +01:00 committed by GitHub
parent a423f45294
commit 719488dda8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 152 additions and 15 deletions

View file

@ -20,7 +20,7 @@
import json
from http import HTTPStatus
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
from unittest.mock import Mock, call
from unittest.mock import Mock, call, patch
from urllib import parse as urlparse
from parameterized import param, parameterized
@ -39,9 +39,10 @@ from synapse.api.constants import (
RoomTypes,
)
from synapse.api.errors import Codes, HttpResponseException
from synapse.appservice import ApplicationService
from synapse.handlers.pagination import PurgeStatus
from synapse.rest import admin
from synapse.rest.client import account, directory, login, profile, room, sync
from synapse.rest.client import account, directory, login, profile, register, room, sync
from synapse.server import HomeServer
from synapse.types import JsonDict, RoomAlias, UserID, create_requester
from synapse.util import Clock
@ -1252,6 +1253,120 @@ class RoomJoinTestCase(RoomBase):
)
class RoomAppserviceTsParamTestCase(unittest.HomeserverTestCase):
servlets = [
room.register_servlets,
synapse.rest.admin.register_servlets,
register.register_servlets,
]
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
self.appservice_user, _ = self.register_appservice_user(
"as_user_potato", self.appservice.token
)
# Create a room as the appservice user.
args = {
"access_token": self.appservice.token,
"user_id": self.appservice_user,
}
channel = self.make_request(
"POST",
f"/_matrix/client/r0/createRoom?{urlparse.urlencode(args)}",
content={"visibility": "public"},
)
assert channel.code == 200
self.room = channel.json_body["room_id"]
self.main_store = self.hs.get_datastores().main
def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
config = self.default_config()
self.appservice = ApplicationService(
token="i_am_an_app_service",
id="1234",
namespaces={"users": [{"regex": r"@as_user.*", "exclusive": True}]},
# Note: this user does not have to match the regex above
sender="@as_main:test",
)
mock_load_appservices = Mock(return_value=[self.appservice])
with patch(
"synapse.storage.databases.main.appservice.load_appservices",
mock_load_appservices,
):
hs = self.setup_test_homeserver(config=config)
return hs
def test_send_event_ts(self) -> None:
"""Test sending a non-state event with a custom timestamp."""
ts = 1
url_params = {
"user_id": self.appservice_user,
"ts": ts,
}
channel = self.make_request(
"PUT",
path=f"/_matrix/client/r0/rooms/{self.room}/send/m.room.message/1234?"
+ urlparse.urlencode(url_params),
content={"body": "test", "msgtype": "m.text"},
access_token=self.appservice.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
event_id = channel.json_body["event_id"]
# Ensure the event was persisted with the correct timestamp.
res = self.get_success(self.main_store.get_event(event_id))
self.assertEquals(ts, res.origin_server_ts)
def test_send_state_event_ts(self) -> None:
"""Test sending a state event with a custom timestamp."""
ts = 1
url_params = {
"user_id": self.appservice_user,
"ts": ts,
}
channel = self.make_request(
"PUT",
path=f"/_matrix/client/r0/rooms/{self.room}/state/m.room.name?"
+ urlparse.urlencode(url_params),
content={"name": "test"},
access_token=self.appservice.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
event_id = channel.json_body["event_id"]
# Ensure the event was persisted with the correct timestamp.
res = self.get_success(self.main_store.get_event(event_id))
self.assertEquals(ts, res.origin_server_ts)
def test_send_membership_event_ts(self) -> None:
"""Test sending a membership event with a custom timestamp."""
ts = 1
url_params = {
"user_id": self.appservice_user,
"ts": ts,
}
channel = self.make_request(
"PUT",
path=f"/_matrix/client/r0/rooms/{self.room}/state/m.room.member/{self.appservice_user}?"
+ urlparse.urlencode(url_params),
content={"membership": "join", "display_name": "test"},
access_token=self.appservice.token,
)
self.assertEqual(channel.code, 200, channel.json_body)
event_id = channel.json_body["event_id"]
# Ensure the event was persisted with the correct timestamp.
res = self.get_success(self.main_store.get_event(event_id))
self.assertEquals(ts, res.origin_server_ts)
class RoomJoinRatelimitTestCase(RoomBase):
user_id = "@sid1:red"