Check room visibility for /event/ requests

Make sure that the user has permission to view the requeseted event for
/event/{eventId} and /room/{roomId}/event/{eventId} requests.

Also check that the event is in the given room for
/room/{roomId}/event/{eventId}, for sanity.
This commit is contained in:
Richard van der Hoff 2018-08-02 15:03:27 +01:00
parent a013404292
commit 0bf5ec0db7
3 changed files with 23 additions and 6 deletions

View File

@ -19,10 +19,12 @@ import random
from twisted.internet import defer from twisted.internet import defer
from synapse.api.constants import EventTypes, Membership from synapse.api.constants import EventTypes, Membership
from synapse.api.errors import AuthError
from synapse.events import EventBase from synapse.events import EventBase
from synapse.events.utils import serialize_event from synapse.events.utils import serialize_event
from synapse.types import UserID from synapse.types import UserID
from synapse.util.logutils import log_function from synapse.util.logutils import log_function
from synapse.visibility import filter_events_for_client
from ._base import BaseHandler from ._base import BaseHandler
@ -129,11 +131,13 @@ class EventStreamHandler(BaseHandler):
class EventHandler(BaseHandler): class EventHandler(BaseHandler):
@defer.inlineCallbacks @defer.inlineCallbacks
def get_event(self, user, event_id): def get_event(self, user, room_id, event_id):
"""Retrieve a single specified event. """Retrieve a single specified event.
Args: Args:
user (synapse.types.UserID): The user requesting the event user (synapse.types.UserID): The user requesting the event
room_id (str|None): The expected room id. We'll return None if the
event's room does not match.
event_id (str): The event ID to obtain. event_id (str): The event ID to obtain.
Returns: Returns:
dict: An event, or None if there is no event matching this ID. dict: An event, or None if there is no event matching this ID.
@ -142,13 +146,26 @@ class EventHandler(BaseHandler):
AuthError if the user does not have the rights to inspect this AuthError if the user does not have the rights to inspect this
event. event.
""" """
event = yield self.store.get_event(event_id) event = yield self.store.get_event(event_id, check_room_id=room_id)
if not event: if not event:
defer.returnValue(None) defer.returnValue(None)
return return
if hasattr(event, "room_id"): users = yield self.store.get_users_in_room(event.room_id)
yield self.auth.check_joined_room(event.room_id, user.to_string()) is_peeking = user.to_string() not in users
filtered = yield filter_events_for_client(
self.store,
user.to_string(),
[event],
is_peeking=is_peeking
)
if not filtered:
raise AuthError(
403,
"You don't have permission to access that event."
)
defer.returnValue(event) defer.returnValue(event)

View File

@ -88,7 +88,7 @@ class EventRestServlet(ClientV1RestServlet):
@defer.inlineCallbacks @defer.inlineCallbacks
def on_GET(self, request, event_id): def on_GET(self, request, event_id):
requester = yield self.auth.get_user_by_req(request) requester = yield self.auth.get_user_by_req(request)
event = yield self.event_handler.get_event(requester.user, event_id) event = yield self.event_handler.get_event(requester.user, None, event_id)
time_now = self.clock.time_msec() time_now = self.clock.time_msec()
if event: if event:

View File

@ -508,7 +508,7 @@ class RoomEventServlet(ClientV1RestServlet):
@defer.inlineCallbacks @defer.inlineCallbacks
def on_GET(self, request, room_id, event_id): def on_GET(self, request, room_id, event_id):
requester = yield self.auth.get_user_by_req(request) requester = yield self.auth.get_user_by_req(request)
event = yield self.event_handler.get_event(requester.user, event_id) event = yield self.event_handler.get_event(requester.user, room_id, event_id)
time_now = self.clock.time_msec() time_now = self.clock.time_msec()
if event: if event: