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

Commit

Permalink
Fix: Pillow error when uploading RGBA image (#3325) (#6241)
Browse files Browse the repository at this point in the history
* commit '81731c6e7':
  Fix: Pillow error when uploading RGBA image (#3325) (#6241)
  Add User-Interactive Auth to /account/3pid/add (#6119)
  Lint
  Changelog
  Discard retention policies when retrieving state
  blacklist more tests
  Newsfile
  Add tests
  Propagate reason in remotely rejected invites
  MSC2367 Allow reason field on all member events
  • Loading branch information
anoadragon453 committed Mar 19, 2020
2 parents 2f57741 + 81731c6 commit 603166f
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .buildkite/worker-blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,10 @@ Don't get pushed for rooms you've muted
Rejected events are not pushed
Test that rejected pushers are removed.
Events come down the correct room

# https://buildkite.com/matrix-dot-org/sytest/builds/326#cca62404-a88a-4fcb-ad41-175fd3377603
Presence changes to UNAVAILABLE are reported to remote room members
If remote user leaves room, changes device and rejoins we see update in sync
uploading self-signing key notifies over federation
Inbound federation can receive redacted events
Outbound federation can request missing events
1 change: 1 addition & 0 deletions changelog.d/6119.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Require User-Interactive Authentication for `/account/3pid/add`, meaning the user's password will be required to add a third-party ID to their account.
1 change: 1 addition & 0 deletions changelog.d/6241.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix error from the Pillow library when uploading RGBA images.
1 change: 1 addition & 0 deletions changelog.d/6434.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for MSC 2367, which allows specifying a reason on all membership events.
4 changes: 2 additions & 2 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1435,9 +1435,9 @@ def on_invite_request(self, origin, pdu):
return event

@defer.inlineCallbacks
def do_remotely_reject_invite(self, target_hosts, room_id, user_id):
def do_remotely_reject_invite(self, target_hosts, room_id, user_id, content):
origin, event, event_format_version = yield self._make_and_verify_event(
target_hosts, room_id, user_id, "leave"
target_hosts, room_id, user_id, "leave", content=content,
)
# Mark as outlier as we don't have any state for this event; we're not
# even in the room.
Expand Down
13 changes: 9 additions & 4 deletions synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ def _remote_join(self, requester, remote_room_hosts, room_id, user, content):
raise NotImplementedError()

@abc.abstractmethod
def _remote_reject_invite(self, requester, remote_room_hosts, room_id, target):
def _remote_reject_invite(
self, requester, remote_room_hosts, room_id, target, content
):
"""Attempt to reject an invite for a room this server is not in. If we
fail to do so we locally mark the invite as rejected.
Expand All @@ -109,6 +111,7 @@ def _remote_reject_invite(self, requester, remote_room_hosts, room_id, target):
reject invite
room_id (str)
target (UserID): The user rejecting the invite
content (dict): The content for the rejection event
Returns:
Deferred[dict]: A dictionary to be returned to the client, may
Expand Down Expand Up @@ -526,7 +529,7 @@ def _update_membership(
# send the rejection to the inviter's HS.
remote_room_hosts = remote_room_hosts + [inviter.domain]
res = yield self._remote_reject_invite(
requester, remote_room_hosts, room_id, target
requester, remote_room_hosts, room_id, target, content,
)
return res

Expand Down Expand Up @@ -1056,13 +1059,15 @@ def _remote_join(self, requester, remote_room_hosts, room_id, user, content):
)

@defer.inlineCallbacks
def _remote_reject_invite(self, requester, remote_room_hosts, room_id, target):
def _remote_reject_invite(
self, requester, remote_room_hosts, room_id, target, content
):
"""Implements RoomMemberHandler._remote_reject_invite
"""
fed_handler = self.federation_handler
try:
ret = yield fed_handler.do_remotely_reject_invite(
remote_room_hosts, room_id, target.to_string()
remote_room_hosts, room_id, target.to_string(), content=content,
)
return ret
except Exception as e:
Expand Down
5 changes: 4 additions & 1 deletion synapse/handlers/room_member_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ def _remote_join(self, requester, remote_room_hosts, room_id, user, content):

return ret

def _remote_reject_invite(self, requester, remote_room_hosts, room_id, target):
def _remote_reject_invite(
self, requester, remote_room_hosts, room_id, target, content
):
"""Implements RoomMemberHandler._remote_reject_invite
"""
return self._remote_reject_client(
requester=requester,
remote_room_hosts=remote_room_hosts,
room_id=room_id,
user_id=target.to_string(),
content=content,
)

def _user_joined_room(self, target, room_id):
Expand Down
7 changes: 5 additions & 2 deletions synapse/replication/http/membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class ReplicationRemoteRejectInviteRestServlet(ReplicationEndpoint):
{
"requester": ...,
"remote_room_hosts": [...],
"content": { ... }
}
"""

Expand All @@ -107,7 +108,7 @@ def __init__(self, hs):
self.clock = hs.get_clock()

@staticmethod
def _serialize_payload(requester, room_id, user_id, remote_room_hosts):
def _serialize_payload(requester, room_id, user_id, remote_room_hosts, content):
"""
Args:
requester(Requester)
Expand All @@ -118,12 +119,14 @@ def _serialize_payload(requester, room_id, user_id, remote_room_hosts):
return {
"requester": requester.serialize(),
"remote_room_hosts": remote_room_hosts,
"content": content,
}

async def _handle_request(self, request, room_id, user_id):
content = parse_json_object_from_request(request)

remote_room_hosts = content["remote_room_hosts"]
event_content = content["content"]

requester = Requester.deserialize(self.store, content["requester"])

Expand All @@ -134,7 +137,7 @@ async def _handle_request(self, request, room_id, user_id):

try:
event = await self.federation_handler.do_remotely_reject_invite(
remote_room_hosts, room_id, user_id
remote_room_hosts, room_id, user_id, event_content,
)
ret = event.get_pdu_json()
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion synapse/rest/client/v1/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ async def on_POST(self, request, room_id, membership_action, txn_id=None):
target = UserID.from_string(content["user_id"])

event_content = None
if "reason" in content and membership_action in ["kick", "ban"]:
if "reason" in content:
event_content = {"reason": content["reason"]}

await self.room_member_handler.update_membership(
Expand Down
5 changes: 5 additions & 0 deletions synapse/rest/client/v2_alpha/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ def __init__(self, hs):
self.auth = hs.get_auth()
self.auth_handler = hs.get_auth_handler()

@interactive_auth_handler
@defer.inlineCallbacks
def on_POST(self, request):
requester = yield self.auth.get_user_by_req(request)
Expand All @@ -735,6 +736,10 @@ def on_POST(self, request):
client_secret = body["client_secret"]
sid = body["sid"]

yield self.auth_handler.validate_user_via_ui_auth(
requester, body, self.hs.get_ip_from_request(request)
)

validation_session = yield self.identity_handler.validate_threepid_session(
client_secret, sid
)
Expand Down
5 changes: 4 additions & 1 deletion synapse/rest/media/v1/thumbnailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,8 @@ def crop(self, width, height, output_type):

def _encode_image(self, output_image, output_type):
output_bytes_io = BytesIO()
output_image.save(output_bytes_io, self.FORMATS[output_type], quality=80)
fmt = self.FORMATS[output_type]
if fmt == "JPEG":
output_image = output_image.convert("RGB")
output_image.save(output_bytes_io, fmt, quality=80)
return output_bytes_io
6 changes: 3 additions & 3 deletions synapse/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ def filter_events_for_client(
retention_policies = {}

for room_id in room_ids:
retention_policies[room_id] = (
yield storage.main.get_retention_policy_for_room(room_id)
)
retention_policies[
room_id
] = yield storage.main.get_retention_policy_for_room(room_id)

def allowed(event):
"""
Expand Down
140 changes: 140 additions & 0 deletions tests/rest/client/v1/test_rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1180,3 +1180,143 @@ def test_per_room_profile_forbidden(self):

res_displayname = channel.json_body["content"]["displayname"]
self.assertEqual(res_displayname, self.displayname, channel.result)


class RoomMembershipReasonTestCase(unittest.HomeserverTestCase):
"""Tests that clients can add a "reason" field to membership events and
that they get correctly added to the generated events and propagated.
"""

servlets = [
synapse.rest.admin.register_servlets_for_client_rest_resource,
room.register_servlets,
login.register_servlets,
]

def prepare(self, reactor, clock, homeserver):
self.creator = self.register_user("creator", "test")
self.creator_tok = self.login("creator", "test")

self.second_user_id = self.register_user("second", "test")
self.second_tok = self.login("second", "test")

self.room_id = self.helper.create_room_as(self.creator, tok=self.creator_tok)

def test_join_reason(self):
reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/join".format(self.room_id),
content={"reason": reason},
access_token=self.second_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_leave_reason(self):
self.helper.join(self.room_id, user=self.second_user_id, tok=self.second_tok)

reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/leave".format(self.room_id),
content={"reason": reason},
access_token=self.second_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_kick_reason(self):
self.helper.join(self.room_id, user=self.second_user_id, tok=self.second_tok)

reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/kick".format(self.room_id),
content={"reason": reason, "user_id": self.second_user_id},
access_token=self.second_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_ban_reason(self):
self.helper.join(self.room_id, user=self.second_user_id, tok=self.second_tok)

reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/ban".format(self.room_id),
content={"reason": reason, "user_id": self.second_user_id},
access_token=self.creator_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_unban_reason(self):
reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/unban".format(self.room_id),
content={"reason": reason, "user_id": self.second_user_id},
access_token=self.creator_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_invite_reason(self):
reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/invite".format(self.room_id),
content={"reason": reason, "user_id": self.second_user_id},
access_token=self.creator_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def test_reject_invite_reason(self):
self.helper.invite(
self.room_id,
src=self.creator,
targ=self.second_user_id,
tok=self.creator_tok,
)

reason = "hello"
request, channel = self.make_request(
"POST",
"/_matrix/client/r0/rooms/{}/leave".format(self.room_id),
content={"reason": reason},
access_token=self.second_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

self._check_for_reason(reason)

def _check_for_reason(self, reason):
request, channel = self.make_request(
"GET",
"/_matrix/client/r0/rooms/{}/state/m.room.member/{}".format(
self.room_id, self.second_user_id
),
access_token=self.creator_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

event_content = channel.json_body

self.assertEqual(event_content.get("reason"), reason, channel.result)

0 comments on commit 603166f

Please sign in to comment.