Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Linearize updates to membership via PUT /state/ #1787

Merged
merged 1 commit into from
Jan 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def _local_membership_update(
duplicate = yield msg_handler.deduplicate_state_event(event, context)
if duplicate is not None:
# Discard the new event since this membership change is a no-op.
return
defer.returnValue(duplicate)

yield msg_handler.handle_new_client_event(
requester,
Expand Down Expand Up @@ -120,6 +120,8 @@ def _local_membership_update(
if prev_member_event.membership == Membership.JOIN:
user_left_room(self.distributor, target, room_id)

defer.returnValue(event)

@defer.inlineCallbacks
def remote_join(self, remote_room_hosts, room_id, user, content):
if len(remote_room_hosts) == 0:
Expand Down Expand Up @@ -187,6 +189,7 @@ def _update_membership(
ratelimit=True,
content=None,
):
content_specified = bool(content)
if content is None:
content = {}

Expand Down Expand Up @@ -229,6 +232,12 @@ def _update_membership(
errcode=Codes.BAD_STATE
)

same_content = content == old_state.content
same_membership = old_membership == effective_membership_state
same_sender = requester.user.to_string() == old_state.sender
if same_sender and same_membership and same_content:
defer.returnValue(old_state)

is_host_in_room = yield self._is_host_in_room(current_state_ids)

if effective_membership_state == Membership.JOIN:
Expand All @@ -247,8 +256,9 @@ def _update_membership(
content["membership"] = Membership.JOIN

profile = self.hs.get_handlers().profile_handler
content["displayname"] = yield profile.get_displayname(target)
content["avatar_url"] = yield profile.get_avatar_url(target)
if not content_specified:
content["displayname"] = yield profile.get_displayname(target)
content["avatar_url"] = yield profile.get_avatar_url(target)

if requester.is_guest:
content["kind"] = "guest"
Expand Down Expand Up @@ -290,7 +300,7 @@ def _update_membership(

defer.returnValue({})

yield self._local_membership_update(
res = yield self._local_membership_update(
requester=requester,
target=target,
room_id=room_id,
Expand All @@ -300,6 +310,7 @@ def _update_membership(
prev_event_ids=latest_event_ids,
content=content,
)
defer.returnValue(res)

@defer.inlineCallbacks
def send_membership_event(
Expand Down
28 changes: 17 additions & 11 deletions synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,23 +152,29 @@ def on_PUT(self, request, room_id, event_type, state_key, txn_id=None):
if state_key is not None:
event_dict["state_key"] = state_key

msg_handler = self.handlers.message_handler
event, context = yield msg_handler.create_event(
event_dict,
token_id=requester.access_token_id,
txn_id=txn_id,
)

if event_type == EventTypes.Member:
yield self.handlers.room_member_handler.send_membership_event(
membership = content.get("membership", None)
event = yield self.handlers.room_member_handler.update_membership(
requester,
event,
context,
target=UserID.from_string(state_key),
room_id=room_id,
action=membership,
content=content,
)
else:
msg_handler = self.handlers.message_handler
event, context = yield msg_handler.create_event(
event_dict,
token_id=requester.access_token_id,
txn_id=txn_id,
)

yield msg_handler.send_nonmember_event(requester, event, context)

defer.returnValue((200, {"event_id": event.event_id}))
ret = {}
if event:
ret = {"event_id": event.event_id}
defer.returnValue((200, ret))


# TODO: Needs unit testing for generic events + feedback
Expand Down
4 changes: 2 additions & 2 deletions tests/rest/client/v1/test_rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ def test_membership_basic_room_perms(self):
# set [invite/join/left] of self, set [invite/join/left] of other,
# expect all 404s because room doesn't exist on any server
for usr in [self.user_id, self.rmcreator_id]:
yield self.join(room=room, user=usr, expect_code=403)
yield self.leave(room=room, user=usr, expect_code=403)
yield self.join(room=room, user=usr, expect_code=404)
yield self.leave(room=room, user=usr, expect_code=404)

@defer.inlineCallbacks
def test_membership_private_room_perms(self):
Expand Down
5 changes: 4 additions & 1 deletion tests/rest/client/v1/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def change_membership(self, room, src, targ, membership, tok=None,
(code, response) = yield self.mock_resource.trigger(
"PUT", path, json.dumps(data)
)
self.assertEquals(expect_code, code, msg=str(response))
self.assertEquals(
expect_code, code,
msg="Expected: %d, got: %d, resp: %r" % (expect_code, code, response)
)

self.auth_user_id = temp_id

Expand Down