|
|
|
@ -18,7 +18,7 @@ from twisted.internet import defer |
|
|
|
|
from ._base import BaseHandler |
|
|
|
|
|
|
|
|
|
from synapse.api.constants import ( |
|
|
|
|
EventTypes, KnownRoomEventKeys, Membership, SearchConstraintTypes |
|
|
|
|
EventTypes, Membership, |
|
|
|
|
) |
|
|
|
|
from synapse.api.errors import SynapseError |
|
|
|
|
from synapse.events.utils import serialize_event |
|
|
|
@ -29,45 +29,6 @@ import logging |
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KEYS_TO_ALLOWED_CONSTRAINT_TYPES = { |
|
|
|
|
KnownRoomEventKeys.CONTENT_BODY: [SearchConstraintTypes.FTS], |
|
|
|
|
KnownRoomEventKeys.CONTENT_MSGTYPE: [SearchConstraintTypes.EXACT], |
|
|
|
|
KnownRoomEventKeys.CONTENT_NAME: [ |
|
|
|
|
SearchConstraintTypes.FTS, |
|
|
|
|
SearchConstraintTypes.EXACT, |
|
|
|
|
SearchConstraintTypes.SUBSTRING, |
|
|
|
|
], |
|
|
|
|
KnownRoomEventKeys.CONTENT_TOPIC: [SearchConstraintTypes.FTS], |
|
|
|
|
KnownRoomEventKeys.SENDER: [SearchConstraintTypes.EXACT], |
|
|
|
|
KnownRoomEventKeys.ORIGIN_SERVER_TS: [SearchConstraintTypes.RANGE], |
|
|
|
|
KnownRoomEventKeys.ROOM_ID: [SearchConstraintTypes.EXACT], |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RoomConstraint(object): |
|
|
|
|
def __init__(self, search_type, keys, value): |
|
|
|
|
self.search_type = search_type |
|
|
|
|
self.keys = keys |
|
|
|
|
self.value = value |
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
def from_dict(cls, d): |
|
|
|
|
search_type = d["type"] |
|
|
|
|
keys = d["keys"] |
|
|
|
|
|
|
|
|
|
for key in keys: |
|
|
|
|
if key not in KEYS_TO_ALLOWED_CONSTRAINT_TYPES: |
|
|
|
|
raise SynapseError(400, "Unrecognized key %r", key) |
|
|
|
|
|
|
|
|
|
if search_type not in KEYS_TO_ALLOWED_CONSTRAINT_TYPES[key]: |
|
|
|
|
raise SynapseError( |
|
|
|
|
400, |
|
|
|
|
"Disallowed constraint type %r for key %r", search_type, key |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return cls(search_type, keys, d["value"]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SearchHandler(BaseHandler): |
|
|
|
|
|
|
|
|
|
def __init__(self, hs): |
|
|
|
@ -121,22 +82,20 @@ class SearchHandler(BaseHandler): |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def search(self, user, content): |
|
|
|
|
constraint_dicts = content["search_categories"]["room_events"]["constraints"] |
|
|
|
|
constraints = [RoomConstraint.from_dict(c)for c in constraint_dicts] |
|
|
|
|
|
|
|
|
|
fts = False |
|
|
|
|
for c in constraints: |
|
|
|
|
if c.search_type == SearchConstraintTypes.FTS: |
|
|
|
|
if fts: |
|
|
|
|
raise SynapseError(400, "Only one constraint can be FTS") |
|
|
|
|
fts = True |
|
|
|
|
try: |
|
|
|
|
search_term = content["search_categories"]["room_events"]["search_term"] |
|
|
|
|
keys = content["search_categories"]["room_events"]["keys"] |
|
|
|
|
except KeyError: |
|
|
|
|
raise SynapseError(400, "Invalid search query") |
|
|
|
|
|
|
|
|
|
rooms = yield self.store.get_rooms_for_user_where_membership_is( |
|
|
|
|
user.to_string(), membership_list=[Membership.JOIN, Membership.LEAVE], |
|
|
|
|
user.to_string(), |
|
|
|
|
membership_list=[Membership.JOIN], |
|
|
|
|
# membership_list=[Membership.JOIN, Membership.LEAVE, Membership.Ban], |
|
|
|
|
) |
|
|
|
|
room_ids = set(r.room_id for r in rooms) |
|
|
|
|
|
|
|
|
|
rank_map, event_map = yield self.store.search_msgs(room_ids, constraints) |
|
|
|
|
rank_map, event_map = yield self.store.search_msgs(room_ids, search_term, keys) |
|
|
|
|
|
|
|
|
|
allowed_events = yield self._filter_events_for_client( |
|
|
|
|
user.to_string(), event_map.values() |
|
|
|
|