diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index 92e1180262..14051aee99 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -267,17 +267,18 @@ class MessageHandler(BaseHandler):
member_event = yield self.auth.check_user_was_in_room(room_id, user_id)
defer.returnValue((member_event.membership, member_event.event_id))
return
- except AuthError:
+ except AuthError, auth_error:
+ visibility = yield self.state_handler.get_current_state(
+ room_id, EventTypes.RoomHistoryVisibility, ""
+ )
+ if (
+ visibility and
+ visibility.content["history_visibility"] == "world_readable"
+ ):
+ defer.returnValue((Membership.JOIN, None))
+ return
if not is_guest:
- raise
-
- visibility = yield self.state_handler.get_current_state(
- room_id, EventTypes.RoomHistoryVisibility, ""
- )
- if visibility.content["history_visibility"] == "world_readable":
- defer.returnValue((Membership.JOIN, None))
- return
- else:
+ raise auth_error
raise AuthError(
403, "Guest access not allowed", errcode=Codes.GUEST_ACCESS_FORBIDDEN
)
@@ -465,7 +466,7 @@ class MessageHandler(BaseHandler):
defer.returnValue(ret)
@defer.inlineCallbacks
- def room_initial_sync(self, user_id, room_id, pagin_config=None):
+ def room_initial_sync(self, user_id, room_id, pagin_config=None, is_guest=False):
"""Capture the a snapshot of a room. If user is currently a member of
the room this will be what is currently in the room. If the user left
the room this will be what was in the room when they left.
@@ -482,15 +483,19 @@ class MessageHandler(BaseHandler):
A JSON serialisable dict with the snapshot of the room.
"""
- member_event = yield self.auth.check_user_was_in_room(room_id, user_id)
+ membership, member_event_id = yield self._check_in_room_or_world_readable(
+ room_id,
+ user_id,
+ is_guest
+ )
- if member_event.membership == Membership.JOIN:
+ if membership == Membership.JOIN:
result = yield self._room_initial_sync_joined(
- user_id, room_id, pagin_config, member_event
+ user_id, room_id, pagin_config, membership, is_guest
)
- elif member_event.membership == Membership.LEAVE:
+ elif membership == Membership.LEAVE:
result = yield self._room_initial_sync_parted(
- user_id, room_id, pagin_config, member_event
+ user_id, room_id, pagin_config, membership, member_event_id, is_guest
)
private_user_data = []
@@ -506,19 +511,19 @@ class MessageHandler(BaseHandler):
@defer.inlineCallbacks
def _room_initial_sync_parted(self, user_id, room_id, pagin_config,
- member_event):
+ membership, member_event_id, is_guest):
room_state = yield self.store.get_state_for_events(
- [member_event.event_id], None
+ [member_event_id], None
)
- room_state = room_state[member_event.event_id]
+ room_state = room_state[member_event_id]
limit = pagin_config.limit if pagin_config else None
if limit is None:
limit = 10
stream_token = yield self.store.get_stream_token_for_event(
- member_event.event_id
+ member_event_id
)
messages, token = yield self.store.get_recent_events_for_room(
@@ -528,7 +533,7 @@ class MessageHandler(BaseHandler):
)
messages = yield self._filter_events_for_client(
- user_id, messages
+ user_id, messages, is_guest=is_guest
)
start_token = StreamToken(token[0], 0, 0, 0, 0)
@@ -537,7 +542,7 @@ class MessageHandler(BaseHandler):
time_now = self.clock.time_msec()
defer.returnValue({
- "membership": member_event.membership,
+ "membership": membership,
"room_id": room_id,
"messages": {
"chunk": [serialize_event(m, time_now) for m in messages],
@@ -551,7 +556,7 @@ class MessageHandler(BaseHandler):
@defer.inlineCallbacks
def _room_initial_sync_joined(self, user_id, room_id, pagin_config,
- member_event):
+ membership, is_guest):
current_state = yield self.state.get_current_state(
room_id=room_id,
)
@@ -583,12 +588,14 @@ class MessageHandler(BaseHandler):
@defer.inlineCallbacks
def get_presence():
- states = yield presence_handler.get_states(
- target_users=[UserID.from_string(m.user_id) for m in room_members],
- auth_user=auth_user,
- as_event=True,
- check_auth=False,
- )
+ states = {}
+ if not is_guest:
+ states = yield presence_handler.get_states(
+ target_users=[UserID.from_string(m.user_id) for m in room_members],
+ auth_user=auth_user,
+ as_event=True,
+ check_auth=False,
+ )
defer.returnValue(states.values())
@@ -608,7 +615,7 @@ class MessageHandler(BaseHandler):
).addErrback(unwrapFirstError)
messages = yield self._filter_events_for_client(
- user_id, messages
+ user_id, messages, is_guest=is_guest, require_all_visible_for_guests=False
)
start_token = now_token.copy_and_replace("room_key", token[0])
@@ -616,8 +623,7 @@ class MessageHandler(BaseHandler):
time_now = self.clock.time_msec()
- defer.returnValue({
- "membership": member_event.membership,
+ ret = {
"room_id": room_id,
"messages": {
"chunk": [serialize_event(m, time_now) for m in messages],
@@ -627,4 +633,8 @@ class MessageHandler(BaseHandler):
"state": state,
"presence": presence,
"receipts": receipts,
- })
+ }
+ if not is_guest:
+ ret["membership"] = membership
+
+ defer.returnValue(ret)
diff --git a/synapse/rest/client/v1/room.py b/synapse/rest/client/v1/room.py
index c583025e30..d298aee3ab 100644
--- a/synapse/rest/client/v1/room.py
+++ b/synapse/rest/client/v1/room.py
@@ -372,12 +372,13 @@ class RoomInitialSyncRestServlet(ClientV1RestServlet):
@defer.inlineCallbacks
def on_GET(self, request, room_id):
- user, _, _ = yield self.auth.get_user_by_req(request)
+ user, _, is_guest = yield self.auth.get_user_by_req(request, allow_guest=True)
pagination_config = PaginationConfig.from_request(request)
content = yield self.handlers.message_handler.room_initial_sync(
room_id=room_id,
user_id=user.to_string(),
pagin_config=pagination_config,
+ is_guest=is_guest,
)
defer.returnValue((200, content))
diff --git a/synapse/state.py b/synapse/state.py
index bb225c39cf..f893df3378 100644
--- a/synapse/state.py
+++ b/synapse/state.py
@@ -307,19 +307,23 @@ class StateHandler(object):
We resolve conflicts in the following order:
1. power levels
- 2. memberships
- 3. other events.
+ 2. join rules
+ 3. memberships
+ 4. other events.
"""
resolved_state = {}
power_key = (EventTypes.PowerLevels, "")
- if power_key in conflicted_state.items():
- power_levels = conflicted_state[power_key]
- resolved_state[power_key] = self._resolve_auth_events(power_levels)
+ if power_key in conflicted_state:
+ events = conflicted_state[power_key]
+ logger.debug("Resolving conflicted power levels %r", events)
+ resolved_state[power_key] = self._resolve_auth_events(
+ events, auth_events)
auth_events.update(resolved_state)
for key, events in conflicted_state.items():
if key[0] == EventTypes.JoinRules:
+ logger.debug("Resolving conflicted join rules %r", events)
resolved_state[key] = self._resolve_auth_events(
events,
auth_events
@@ -329,6 +333,7 @@ class StateHandler(object):
for key, events in conflicted_state.items():
if key[0] == EventTypes.Member:
+ logger.debug("Resolving conflicted member lists %r", events)
resolved_state[key] = self._resolve_auth_events(
events,
auth_events
@@ -338,6 +343,7 @@ class StateHandler(object):
for key, events in conflicted_state.items():
if key not in resolved_state:
+ logger.debug("Resolving conflicted state %r:%r", key, events)
resolved_state[key] = self._resolve_normal_events(
events, auth_events
)
|