Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 6c68e87

Browse files
authored
Remove the /send_relation endpoint. (#11682)
This was removed from MSC2674 before that was approved and is not used by any known clients.
1 parent 201c48c commit 6c68e87

File tree

3 files changed

+19
-133
lines changed

3 files changed

+19
-133
lines changed

changelog.d/11682.removal

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove the unstable `/send_relation` endpoint.

synapse/rest/client/relations.py

+5-120
Original file line numberDiff line numberDiff line change
@@ -19,141 +19,27 @@
1919
"""
2020

2121
import logging
22-
from typing import TYPE_CHECKING, Awaitable, Optional, Tuple
22+
from typing import TYPE_CHECKING, Optional, Tuple
2323

24-
from synapse.api.constants import EventTypes, RelationTypes
25-
from synapse.api.errors import ShadowBanError, SynapseError
24+
from synapse.api.constants import RelationTypes
25+
from synapse.api.errors import SynapseError
2626
from synapse.http.server import HttpServer
27-
from synapse.http.servlet import (
28-
RestServlet,
29-
parse_integer,
30-
parse_json_object_from_request,
31-
parse_string,
32-
)
27+
from synapse.http.servlet import RestServlet, parse_integer, parse_string
3328
from synapse.http.site import SynapseRequest
34-
from synapse.rest.client.transactions import HttpTransactionCache
29+
from synapse.rest.client._base import client_patterns
3530
from synapse.storage.relations import (
3631
AggregationPaginationToken,
3732
PaginationChunk,
3833
RelationPaginationToken,
3934
)
4035
from synapse.types import JsonDict
41-
from synapse.util.stringutils import random_string
42-
43-
from ._base import client_patterns
4436

4537
if TYPE_CHECKING:
4638
from synapse.server import HomeServer
4739

4840
logger = logging.getLogger(__name__)
4941

5042

51-
class RelationSendServlet(RestServlet):
52-
"""Helper API for sending events that have relation data.
53-
54-
Example API shape to send a 👍 reaction to a room:
55-
56-
POST /rooms/!foo/send_relation/$bar/m.annotation/m.reaction?key=%F0%9F%91%8D
57-
{}
58-
59-
{
60-
"event_id": "$foobar"
61-
}
62-
"""
63-
64-
PATTERN = (
65-
"/rooms/(?P<room_id>[^/]*)/send_relation"
66-
"/(?P<parent_id>[^/]*)/(?P<relation_type>[^/]*)/(?P<event_type>[^/]*)"
67-
)
68-
69-
def __init__(self, hs: "HomeServer"):
70-
super().__init__()
71-
self.auth = hs.get_auth()
72-
self.event_creation_handler = hs.get_event_creation_handler()
73-
self.txns = HttpTransactionCache(hs)
74-
75-
def register(self, http_server: HttpServer) -> None:
76-
http_server.register_paths(
77-
"POST",
78-
client_patterns(self.PATTERN + "$", releases=()),
79-
self.on_PUT_or_POST,
80-
self.__class__.__name__,
81-
)
82-
http_server.register_paths(
83-
"PUT",
84-
client_patterns(self.PATTERN + "/(?P<txn_id>[^/]*)$", releases=()),
85-
self.on_PUT,
86-
self.__class__.__name__,
87-
)
88-
89-
def on_PUT(
90-
self,
91-
request: SynapseRequest,
92-
room_id: str,
93-
parent_id: str,
94-
relation_type: str,
95-
event_type: str,
96-
txn_id: Optional[str] = None,
97-
) -> Awaitable[Tuple[int, JsonDict]]:
98-
return self.txns.fetch_or_execute_request(
99-
request,
100-
self.on_PUT_or_POST,
101-
request,
102-
room_id,
103-
parent_id,
104-
relation_type,
105-
event_type,
106-
txn_id,
107-
)
108-
109-
async def on_PUT_or_POST(
110-
self,
111-
request: SynapseRequest,
112-
room_id: str,
113-
parent_id: str,
114-
relation_type: str,
115-
event_type: str,
116-
txn_id: Optional[str] = None,
117-
) -> Tuple[int, JsonDict]:
118-
requester = await self.auth.get_user_by_req(request, allow_guest=True)
119-
120-
if event_type == EventTypes.Member:
121-
# Add relations to a membership is meaningless, so we just deny it
122-
# at the CS API rather than trying to handle it correctly.
123-
raise SynapseError(400, "Cannot send member events with relations")
124-
125-
content = parse_json_object_from_request(request)
126-
127-
aggregation_key = parse_string(request, "key", encoding="utf-8")
128-
129-
content["m.relates_to"] = {
130-
"event_id": parent_id,
131-
"rel_type": relation_type,
132-
}
133-
if aggregation_key is not None:
134-
content["m.relates_to"]["key"] = aggregation_key
135-
136-
event_dict = {
137-
"type": event_type,
138-
"content": content,
139-
"room_id": room_id,
140-
"sender": requester.user.to_string(),
141-
}
142-
143-
try:
144-
(
145-
event,
146-
_,
147-
) = await self.event_creation_handler.create_and_send_nonmember_event(
148-
requester, event_dict=event_dict, txn_id=txn_id
149-
)
150-
event_id = event.event_id
151-
except ShadowBanError:
152-
event_id = "$" + random_string(43)
153-
154-
return 200, {"event_id": event_id}
155-
156-
15743
class RelationPaginationServlet(RestServlet):
15844
"""API to paginate relations on an event by topological ordering, optionally
15945
filtered by relation type and event type.
@@ -431,7 +317,6 @@ async def on_GET(
431317

432318

433319
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
434-
RelationSendServlet(hs).register(http_server)
435320
RelationPaginationServlet(hs).register(http_server)
436321
RelationAggregationPaginationServlet(hs).register(http_server)
437322
RelationAggregationGroupPaginationServlet(hs).register(http_server)

tests/rest/client/test_relations.py

+13-13
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,6 @@ def test_send_relation(self):
9393
channel.json_body,
9494
)
9595

96-
def test_deny_membership(self):
97-
"""Test that we deny relations on membership events"""
98-
channel = self._send_relation(RelationTypes.ANNOTATION, EventTypes.Member)
99-
self.assertEquals(400, channel.code, channel.json_body)
100-
10196
def test_deny_invalid_event(self):
10297
"""Test that we deny relations on non-existant events"""
10398
channel = self._send_relation(
@@ -1119,7 +1114,8 @@ def _send_relation(
11191114
relation_type: One of `RelationTypes`
11201115
event_type: The type of the event to create
11211116
key: The aggregation key used for m.annotation relation type.
1122-
content: The content of the created event.
1117+
content: The content of the created event. Will be modified to configure
1118+
the m.relates_to key based on the other provided parameters.
11231119
access_token: The access token used to send the relation, defaults
11241120
to `self.user_token`
11251121
parent_id: The event_id this relation relates to. If None, then self.parent_id
@@ -1130,17 +1126,21 @@ def _send_relation(
11301126
if not access_token:
11311127
access_token = self.user_token
11321128

1133-
query = ""
1134-
if key:
1135-
query = "?key=" + urllib.parse.quote_plus(key.encode("utf-8"))
1136-
11371129
original_id = parent_id if parent_id else self.parent_id
11381130

1131+
if content is None:
1132+
content = {}
1133+
content["m.relates_to"] = {
1134+
"event_id": original_id,
1135+
"rel_type": relation_type,
1136+
}
1137+
if key is not None:
1138+
content["m.relates_to"]["key"] = key
1139+
11391140
channel = self.make_request(
11401141
"POST",
1141-
"/_matrix/client/unstable/rooms/%s/send_relation/%s/%s/%s%s"
1142-
% (self.room, original_id, relation_type, event_type, query),
1143-
content or {},
1142+
f"/_matrix/client/v3/rooms/{self.room}/send/{event_type}",
1143+
content,
11441144
access_token=access_token,
11451145
)
11461146
return channel

0 commit comments

Comments
 (0)