Allow guest access to /sync

This commit is contained in:
Mark Haines 2015-12-22 11:21:03 +00:00
parent 45a9e0ae0c
commit c3fff251a9
1 changed files with 98 additions and 46 deletions

View File

@ -15,8 +15,8 @@
from ._base import BaseHandler from ._base import BaseHandler
from synapse.streams.config import PaginationConfig
from synapse.api.constants import Membership, EventTypes from synapse.api.constants import Membership, EventTypes
from synapse.api.errors import AuthError
from synapse.util import unwrapFirstError from synapse.util import unwrapFirstError
from twisted.internet import defer from twisted.internet import defer
@ -118,6 +118,8 @@ class SyncResult(collections.namedtuple("SyncResult", [
self.presence or self.joined or self.invited self.presence or self.joined or self.invited
) )
GuestRoom = collections.namedtuple("GuestRoom", ("room_id", "membership"))
class SyncHandler(BaseHandler): class SyncHandler(BaseHandler):
@ -136,6 +138,12 @@ class SyncHandler(BaseHandler):
A Deferred SyncResult. A Deferred SyncResult.
""" """
if sync_config.is_guest:
for room_id in sync_config.filter.list_rooms():
world_readable = yield self._is_world_readable(room_id)
if not world_readable:
raise AuthError(403, "Guest access not allowed")
if timeout == 0 or since_token is None or full_state: if timeout == 0 or since_token is None or full_state:
# we are going to return immediately, so don't bother calling # we are going to return immediately, so don't bother calling
# notifier.wait_for_events. # notifier.wait_for_events.
@ -152,6 +160,17 @@ class SyncHandler(BaseHandler):
) )
defer.returnValue(result) defer.returnValue(result)
@defer.inlineCallbacks
def _is_world_readable(self, room_id):
state = yield self.hs.get_state_handler().get_current_state(
room_id,
EventTypes.RoomHistoryVisibility
)
if state and "history_visibility" in state.content:
defer.returnValue(state.content["history_visibility"] == "world_readable")
else:
defer.returnValue(False)
def current_sync_for_user(self, sync_config, since_token=None, def current_sync_for_user(self, sync_config, since_token=None,
full_state=False): full_state=False):
"""Get the sync for client needed to match what the server has now. """Get the sync for client needed to match what the server has now.
@ -175,37 +194,54 @@ class SyncHandler(BaseHandler):
""" """
now_token = yield self.event_sources.get_current_token() now_token = yield self.event_sources.get_current_token()
now_token, ephemeral_by_room = yield self.ephemeral_by_room( if sync_config.is_guest:
sync_config, now_token room_list = []
) for room_id in sync_config.filter.list_rooms():
room_list.append(GuestRoom(room_id, Membership.JOIN))
presence_stream = self.event_sources.sources["presence"] account_data = {}
# TODO (mjark): This looks wrong, shouldn't we be getting the presence account_data_by_room = {}
# UP to the present rather than after the present? tags_by_room = {}
pagination_config = PaginationConfig(from_token=now_token)
presence, _ = yield presence_stream.get_pagination_rows(
user=sync_config.user,
pagination_config=pagination_config.get_source_config("presence"),
key=None
)
membership_list = (Membership.INVITE, Membership.JOIN) # TODO: Hook up read receipts
if sync_config.filter.include_leave: ephemeral_by_room = {}
membership_list += (Membership.LEAVE, Membership.BAN)
room_list = yield self.store.get_rooms_for_user_where_membership_is( else:
user_id=sync_config.user.to_string(), now_token, ephemeral_by_room = yield self.ephemeral_by_room(
membership_list=membership_list sync_config, now_token
) )
account_data, account_data_by_room = ( membership_list = (Membership.INVITE, Membership.JOIN)
yield self.store.get_account_data_for_user( if sync_config.filter.include_leave:
membership_list += (Membership.LEAVE, Membership.BAN)
room_list = yield self.store.get_rooms_for_user_where_membership_is(
user_id=sync_config.user.to_string(),
membership_list=membership_list
)
account_data, account_data_by_room = (
yield self.store.get_account_data_for_user(
sync_config.user.to_string()
)
)
tags_by_room = yield self.store.get_tags_for_user(
sync_config.user.to_string() sync_config.user.to_string()
) )
)
tags_by_room = yield self.store.get_tags_for_user( presence_stream = self.event_sources.sources["presence"]
sync_config.user.to_string()
joined_room_ids = [
room.room_id for room in room_list
if room.membership == Membership.JOIN
]
presence, _ = yield presence_stream.get_new_events(
from_key=0,
user=sync_config.user,
room_ids=joined_room_ids,
is_guest=sync_config.is_guest,
) )
joined = [] joined = []
@ -411,8 +447,36 @@ class SyncHandler(BaseHandler):
""" """
now_token = yield self.event_sources.get_current_token() now_token = yield self.event_sources.get_current_token()
rooms = yield self.store.get_rooms_for_user(sync_config.user.to_string()) if sync_config.is_guest:
room_ids = [room.room_id for room in rooms] room_ids = sync_config.filter.list_rooms()
ephemeral_by_room = {}
tags_by_room = {}
account_data = {}
account_data_by_room = {}
else:
rooms = yield self.store.get_rooms_for_user(
sync_config.user.to_string()
)
room_ids = [room.room_id for room in rooms]
now_token, ephemeral_by_room = yield self.ephemeral_by_room(
sync_config, now_token, since_token
)
tags_by_room = yield self.store.get_updated_tags(
sync_config.user.to_string(),
since_token.account_data_key,
)
account_data, account_data_by_room = (
yield self.store.get_updated_account_data_for_user(
sync_config.user.to_string(),
since_token.account_data_key,
)
)
presence_source = self.event_sources.sources["presence"] presence_source = self.event_sources.sources["presence"]
presence, presence_key = yield presence_source.get_new_events( presence, presence_key = yield presence_source.get_new_events(
@ -420,15 +484,10 @@ class SyncHandler(BaseHandler):
from_key=since_token.presence_key, from_key=since_token.presence_key,
limit=sync_config.filter.presence_limit(), limit=sync_config.filter.presence_limit(),
room_ids=room_ids, room_ids=room_ids,
# /sync doesn't support guest access, they can't get to this point in code is_guest=sync_config.is_guest,
is_guest=False,
) )
now_token = now_token.copy_and_replace("presence_key", presence_key) now_token = now_token.copy_and_replace("presence_key", presence_key)
now_token, ephemeral_by_room = yield self.ephemeral_by_room(
sync_config, now_token, since_token
)
rm_handler = self.hs.get_handlers().room_member_handler rm_handler = self.hs.get_handlers().room_member_handler
app_service = yield self.store.get_app_service_by_user_id( app_service = yield self.store.get_app_service_by_user_id(
sync_config.user.to_string() sync_config.user.to_string()
@ -448,18 +507,8 @@ class SyncHandler(BaseHandler):
from_key=since_token.room_key, from_key=since_token.room_key,
to_key=now_token.room_key, to_key=now_token.room_key,
limit=timeline_limit + 1, limit=timeline_limit + 1,
) room_ids=room_ids if sync_config.is_guest else (),
is_guest=sync_config.is_guest,
tags_by_room = yield self.store.get_updated_tags(
sync_config.user.to_string(),
since_token.account_data_key,
)
account_data, account_data_by_room = (
yield self.store.get_updated_account_data_for_user(
sync_config.user.to_string(),
since_token.account_data_key,
)
) )
joined = [] joined = []
@ -591,7 +640,10 @@ class SyncHandler(BaseHandler):
end_key = "s" + room_key.split('-')[-1] end_key = "s" + room_key.split('-')[-1]
loaded_recents = sync_config.filter.filter_room_timeline(events) loaded_recents = sync_config.filter.filter_room_timeline(events)
loaded_recents = yield self._filter_events_for_client( loaded_recents = yield self._filter_events_for_client(
sync_config.user.to_string(), loaded_recents, sync_config.user.to_string(),
loaded_recents,
is_guest=sync_config.is_guest,
require_all_visible_for_guests=False
) )
loaded_recents.extend(recents) loaded_recents.extend(recents)
recents = loaded_recents recents = loaded_recents