Esempio n. 1
0
    async def on_GET(
        self,
        request: SynapseRequest,
        room_id: str,
        parent_id: str,
        relation_type: Optional[str] = None,
        event_type: Optional[str] = None,
    ) -> Tuple[int, JsonDict]:
        requester = await self.auth.get_user_by_req(request, allow_guest=True)

        await self.auth.check_user_in_room_or_world_readable(
            room_id,
            requester.user.to_string(),
            allow_departed_users=True,
        )

        # This checks that a) the event exists and b) the user is allowed to
        # view it.
        event = await self.event_handler.get_event(requester.user, room_id,
                                                   parent_id)
        if event is None:
            raise SynapseError(404, "Unknown parent event.")

        if relation_type not in (RelationTypes.ANNOTATION, None):
            raise SynapseError(
                400, f"Relation type must be '{RelationTypes.ANNOTATION}'")

        limit = parse_integer(request, "limit", default=5)
        from_token_str = parse_string(request, "from")
        to_token_str = parse_string(request, "to")

        if event.internal_metadata.is_redacted():
            # If the event is redacted, return an empty list of relations
            pagination_chunk = PaginationChunk(chunk=[])
        else:
            # Return the relations
            from_token = None
            if from_token_str:
                from_token = AggregationPaginationToken.from_string(
                    from_token_str)

            to_token = None
            if to_token_str:
                to_token = AggregationPaginationToken.from_string(to_token_str)

            pagination_chunk = await self.store.get_aggregation_groups_for_event(
                event_id=parent_id,
                room_id=room_id,
                event_type=event_type,
                limit=limit,
                from_token=from_token,
                to_token=to_token,
            )

        return 200, pagination_chunk.to_dict()
Esempio n. 2
0
    def on_GET(self,
               request,
               room_id,
               parent_id,
               relation_type=None,
               event_type=None):
        requester = yield self.auth.get_user_by_req(request, allow_guest=True)

        yield self.auth.check_in_room_or_world_readable(
            room_id, requester.user.to_string())

        # This checks that a) the event exists and b) the user is allowed to
        # view it.
        event = yield self.event_handler.get_event(requester.user, room_id,
                                                   parent_id)

        if relation_type not in (RelationTypes.ANNOTATION, None):
            raise SynapseError(400, "Relation type must be 'annotation'")

        limit = parse_integer(request, "limit", default=5)
        from_token = parse_string(request, "from")
        to_token = parse_string(request, "to")

        if event.internal_metadata.is_redacted():
            # If the event is redacted, return an empty list of relations
            pagination_chunk = PaginationChunk(chunk=[])
        else:
            # Return the relations
            if from_token:
                from_token = AggregationPaginationToken.from_string(from_token)

            if to_token:
                to_token = AggregationPaginationToken.from_string(to_token)

            pagination_chunk = yield self.store.get_aggregation_groups_for_event(
                event_id=parent_id,
                event_type=event_type,
                limit=limit,
                from_token=from_token,
                to_token=to_token,
            )

        defer.returnValue((200, pagination_chunk.to_dict()))
Esempio n. 3
0
        def _get_aggregation_groups_for_event_txn(txn):
            txn.execute(sql, where_args + [limit + 1])

            next_batch = None
            events = []
            for row in txn:
                events.append({"type": row[0], "key": row[1], "count": row[2]})
                next_batch = AggregationPaginationToken(row[2], row[3])

            if len(events) <= limit:
                next_batch = None

            return PaginationChunk(chunk=list(events[:limit]),
                                   next_batch=next_batch,
                                   prev_batch=from_token)
Esempio n. 4
0
        def _get_recent_references_for_event_txn(txn):
            txn.execute(sql, where_args + [limit + 1])

            last_topo_id = None
            last_stream_id = None
            events = []
            for row in txn:
                events.append({"event_id": row[0]})
                last_topo_id = row[1]
                last_stream_id = row[2]

            next_batch = None
            if len(events) > limit and last_topo_id and last_stream_id:
                next_batch = RelationPaginationToken(last_topo_id, last_stream_id)

            return PaginationChunk(
                chunk=list(events[:limit]), next_batch=next_batch, prev_batch=from_token
            )
Esempio n. 5
0
    async def on_GET(self,
                     request,
                     room_id,
                     parent_id,
                     relation_type=None,
                     event_type=None):
        requester = await self.auth.get_user_by_req(request, allow_guest=True)

        await self.auth.check_user_in_room_or_world_readable(
            room_id, requester.user.to_string(), allow_departed_users=True)

        # This gets the original event and checks that a) the event exists and
        # b) the user is allowed to view it.
        event = await self.event_handler.get_event(requester.user, room_id,
                                                   parent_id)

        limit = parse_integer(request, "limit", default=5)
        from_token_str = parse_string(request, "from")
        to_token_str = parse_string(request, "to")

        if event.internal_metadata.is_redacted():
            # If the event is redacted, return an empty list of relations
            pagination_chunk = PaginationChunk(chunk=[])
        else:
            # Return the relations
            from_token = None
            if from_token_str:
                from_token = RelationPaginationToken.from_string(
                    from_token_str)

            to_token = None
            if to_token_str:
                to_token = RelationPaginationToken.from_string(to_token_str)

            pagination_chunk = await self.store.get_relations_for_event(
                event_id=parent_id,
                relation_type=relation_type,
                event_type=event_type,
                limit=limit,
                from_token=from_token,
                to_token=to_token,
            )

        events = await self.store.get_events_as_list(
            [c["event_id"] for c in pagination_chunk.chunk])

        now = self.clock.time_msec()
        # We set bundle_aggregations to False when retrieving the original
        # event because we want the content before relations were applied to
        # it.
        original_event = await self._event_serializer.serialize_event(
            event, now, bundle_aggregations=False)
        # Similarly, we don't allow relations to be applied to relations, so we
        # return the original relations without any aggregations on top of them
        # here.
        events = await self._event_serializer.serialize_events(
            events, now, bundle_aggregations=False)

        return_value = pagination_chunk.to_dict()
        return_value["chunk"] = events
        return_value["original_event"] = original_event

        return 200, return_value
Esempio n. 6
0
    async def on_GET(
        self,
        request: SynapseRequest,
        room_id: str,
        parent_id: str,
        relation_type: Optional[str] = None,
        event_type: Optional[str] = None,
    ) -> Tuple[int, JsonDict]:
        requester = await self.auth.get_user_by_req(request, allow_guest=True)

        await self.auth.check_user_in_room_or_world_readable(
            room_id, requester.user.to_string(), allow_departed_users=True)

        # This gets the original event and checks that a) the event exists and
        # b) the user is allowed to view it.
        event = await self.event_handler.get_event(requester.user, room_id,
                                                   parent_id)
        if event is None:
            raise SynapseError(404, "Unknown parent event.")

        limit = parse_integer(request, "limit", default=5)
        from_token_str = parse_string(request, "from")
        to_token_str = parse_string(request, "to")

        if event.internal_metadata.is_redacted():
            # If the event is redacted, return an empty list of relations
            pagination_chunk = PaginationChunk(chunk=[])
        else:
            # Return the relations
            from_token = None
            if from_token_str:
                from_token = RelationPaginationToken.from_string(
                    from_token_str)

            to_token = None
            if to_token_str:
                to_token = RelationPaginationToken.from_string(to_token_str)

            pagination_chunk = await self.store.get_relations_for_event(
                event_id=parent_id,
                room_id=room_id,
                relation_type=relation_type,
                event_type=event_type,
                limit=limit,
                from_token=from_token,
                to_token=to_token,
            )

        events = await self.store.get_events_as_list(
            [c["event_id"] for c in pagination_chunk.chunk])

        now = self.clock.time_msec()
        # Do not bundle aggregations when retrieving the original event because
        # we want the content before relations are applied to it.
        original_event = self._event_serializer.serialize_event(
            event, now, bundle_aggregations=None)
        # The relations returned for the requested event do include their
        # bundled aggregations.
        aggregations = await self.store.get_bundled_aggregations(
            events, requester.user.to_string())
        serialized_events = self._event_serializer.serialize_events(
            events, now, bundle_aggregations=aggregations)

        return_value = pagination_chunk.to_dict()
        return_value["chunk"] = serialized_events
        return_value["original_event"] = original_event

        return 200, return_value