Remove the /send_relation endpoint. (#11682)

This was removed from MSC2674 before that was approved
and is not used by any known clients.
pull/11707/head
Patrick Cloke 2022-01-06 14:00:34 -05:00 committed by GitHub
parent 201c48c8de
commit 6c68e874b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 133 deletions

View File

@ -0,0 +1 @@
Remove the unstable `/send_relation` endpoint.

View File

@ -19,28 +19,20 @@ any time to reflect changes in the MSC.
""" """
import logging import logging
from typing import TYPE_CHECKING, Awaitable, Optional, Tuple from typing import TYPE_CHECKING, Optional, Tuple
from synapse.api.constants import EventTypes, RelationTypes from synapse.api.constants import RelationTypes
from synapse.api.errors import ShadowBanError, SynapseError from synapse.api.errors import SynapseError
from synapse.http.server import HttpServer from synapse.http.server import HttpServer
from synapse.http.servlet import ( from synapse.http.servlet import RestServlet, parse_integer, parse_string
RestServlet,
parse_integer,
parse_json_object_from_request,
parse_string,
)
from synapse.http.site import SynapseRequest from synapse.http.site import SynapseRequest
from synapse.rest.client.transactions import HttpTransactionCache from synapse.rest.client._base import client_patterns
from synapse.storage.relations import ( from synapse.storage.relations import (
AggregationPaginationToken, AggregationPaginationToken,
PaginationChunk, PaginationChunk,
RelationPaginationToken, RelationPaginationToken,
) )
from synapse.types import JsonDict from synapse.types import JsonDict
from synapse.util.stringutils import random_string
from ._base import client_patterns
if TYPE_CHECKING: if TYPE_CHECKING:
from synapse.server import HomeServer from synapse.server import HomeServer
@ -48,112 +40,6 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class RelationSendServlet(RestServlet):
"""Helper API for sending events that have relation data.
Example API shape to send a 👍 reaction to a room:
POST /rooms/!foo/send_relation/$bar/m.annotation/m.reaction?key=%F0%9F%91%8D
{}
{
"event_id": "$foobar"
}
"""
PATTERN = (
"/rooms/(?P<room_id>[^/]*)/send_relation"
"/(?P<parent_id>[^/]*)/(?P<relation_type>[^/]*)/(?P<event_type>[^/]*)"
)
def __init__(self, hs: "HomeServer"):
super().__init__()
self.auth = hs.get_auth()
self.event_creation_handler = hs.get_event_creation_handler()
self.txns = HttpTransactionCache(hs)
def register(self, http_server: HttpServer) -> None:
http_server.register_paths(
"POST",
client_patterns(self.PATTERN + "$", releases=()),
self.on_PUT_or_POST,
self.__class__.__name__,
)
http_server.register_paths(
"PUT",
client_patterns(self.PATTERN + "/(?P<txn_id>[^/]*)$", releases=()),
self.on_PUT,
self.__class__.__name__,
)
def on_PUT(
self,
request: SynapseRequest,
room_id: str,
parent_id: str,
relation_type: str,
event_type: str,
txn_id: Optional[str] = None,
) -> Awaitable[Tuple[int, JsonDict]]:
return self.txns.fetch_or_execute_request(
request,
self.on_PUT_or_POST,
request,
room_id,
parent_id,
relation_type,
event_type,
txn_id,
)
async def on_PUT_or_POST(
self,
request: SynapseRequest,
room_id: str,
parent_id: str,
relation_type: str,
event_type: str,
txn_id: Optional[str] = None,
) -> Tuple[int, JsonDict]:
requester = await self.auth.get_user_by_req(request, allow_guest=True)
if event_type == EventTypes.Member:
# Add relations to a membership is meaningless, so we just deny it
# at the CS API rather than trying to handle it correctly.
raise SynapseError(400, "Cannot send member events with relations")
content = parse_json_object_from_request(request)
aggregation_key = parse_string(request, "key", encoding="utf-8")
content["m.relates_to"] = {
"event_id": parent_id,
"rel_type": relation_type,
}
if aggregation_key is not None:
content["m.relates_to"]["key"] = aggregation_key
event_dict = {
"type": event_type,
"content": content,
"room_id": room_id,
"sender": requester.user.to_string(),
}
try:
(
event,
_,
) = await self.event_creation_handler.create_and_send_nonmember_event(
requester, event_dict=event_dict, txn_id=txn_id
)
event_id = event.event_id
except ShadowBanError:
event_id = "$" + random_string(43)
return 200, {"event_id": event_id}
class RelationPaginationServlet(RestServlet): class RelationPaginationServlet(RestServlet):
"""API to paginate relations on an event by topological ordering, optionally """API to paginate relations on an event by topological ordering, optionally
filtered by relation type and event type. filtered by relation type and event type.
@ -431,7 +317,6 @@ class RelationAggregationGroupPaginationServlet(RestServlet):
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
RelationSendServlet(hs).register(http_server)
RelationPaginationServlet(hs).register(http_server) RelationPaginationServlet(hs).register(http_server)
RelationAggregationPaginationServlet(hs).register(http_server) RelationAggregationPaginationServlet(hs).register(http_server)
RelationAggregationGroupPaginationServlet(hs).register(http_server) RelationAggregationGroupPaginationServlet(hs).register(http_server)

View File

@ -93,11 +93,6 @@ class RelationsTestCase(unittest.HomeserverTestCase):
channel.json_body, channel.json_body,
) )
def test_deny_membership(self):
"""Test that we deny relations on membership events"""
channel = self._send_relation(RelationTypes.ANNOTATION, EventTypes.Member)
self.assertEquals(400, channel.code, channel.json_body)
def test_deny_invalid_event(self): def test_deny_invalid_event(self):
"""Test that we deny relations on non-existant events""" """Test that we deny relations on non-existant events"""
channel = self._send_relation( channel = self._send_relation(
@ -1119,7 +1114,8 @@ class RelationsTestCase(unittest.HomeserverTestCase):
relation_type: One of `RelationTypes` relation_type: One of `RelationTypes`
event_type: The type of the event to create event_type: The type of the event to create
key: The aggregation key used for m.annotation relation type. key: The aggregation key used for m.annotation relation type.
content: The content of the created event. content: The content of the created event. Will be modified to configure
the m.relates_to key based on the other provided parameters.
access_token: The access token used to send the relation, defaults access_token: The access token used to send the relation, defaults
to `self.user_token` to `self.user_token`
parent_id: The event_id this relation relates to. If None, then self.parent_id parent_id: The event_id this relation relates to. If None, then self.parent_id
@ -1130,17 +1126,21 @@ class RelationsTestCase(unittest.HomeserverTestCase):
if not access_token: if not access_token:
access_token = self.user_token access_token = self.user_token
query = ""
if key:
query = "?key=" + urllib.parse.quote_plus(key.encode("utf-8"))
original_id = parent_id if parent_id else self.parent_id original_id = parent_id if parent_id else self.parent_id
if content is None:
content = {}
content["m.relates_to"] = {
"event_id": original_id,
"rel_type": relation_type,
}
if key is not None:
content["m.relates_to"]["key"] = key
channel = self.make_request( channel = self.make_request(
"POST", "POST",
"/_matrix/client/unstable/rooms/%s/send_relation/%s/%s/%s%s" f"/_matrix/client/v3/rooms/{self.room}/send/{event_type}",
% (self.room, original_id, relation_type, event_type, query), content,
content or {},
access_token=access_token, access_token=access_token,
) )
return channel return channel