diff options
author | Brendan Abolivier <babolivier@matrix.org> | 2022-01-28 14:00:12 +0000 |
---|---|---|
committer | Brendan Abolivier <babolivier@matrix.org> | 2022-01-28 14:00:12 +0000 |
commit | 4df1d1231be65bf265b5f3f67fa02965bad9cfc6 (patch) | |
tree | f7ea3d2dde62c9c3a3f2c62cdce68c6add64fe97 | |
parent | Add tests (diff) | |
download | synapse-4df1d1231be65bf265b5f3f67fa02965bad9cfc6.tar.xz |
Incorporate review
-rw-r--r-- | synapse/config/server.py | 6 | ||||
-rw-r--r-- | synapse/handlers/profile.py | 24 | ||||
-rw-r--r-- | synapse/handlers/room_member.py | 7 | ||||
-rw-r--r-- | tests/handlers/test_profile.py | 54 | ||||
-rw-r--r-- | tests/rest/client/test_profile.py | 40 |
5 files changed, 45 insertions, 86 deletions
diff --git a/synapse/config/server.py b/synapse/config/server.py index 26f1177e64..a460cf25b4 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -1181,16 +1181,14 @@ class ServerConfig(Config): # #allow_per_room_profiles: false - # The largest allowed size for a user avatar. If not defined, no - # restriction will be imposed. + # The largest allowed file size for a user avatar. Defaults to no restriction. # # Note that user avatar changes will not work if this is set without # using Synapse's media repository. # #max_avatar_size: 10M - # Allow mimetypes for a user avatar. If not defined, no restriction will - # be imposed. + # The MIME types allowed for user avatars. Defaults to no restriction. # # Note that user avatar changes will not work if this is set without # using Synapse's media repository. diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py index 33f8678e50..36e3ad2ba9 100644 --- a/synapse/handlers/profile.py +++ b/synapse/handlers/profile.py @@ -293,7 +293,8 @@ class ProfileHandler: 400, "Avatar URL is too long (max %i)" % (MAX_AVATAR_URL_LEN,) ) - await self.check_avatar_size_and_mime_type(new_avatar_url) + if not await self.check_avatar_size_and_mime_type(new_avatar_url): + raise SynapseError(403, "This avatar is not allowed", Codes.FORBIDDEN) avatar_url_to_set: Optional[str] = new_avatar_url if new_avatar_url == "": @@ -316,22 +317,8 @@ class ProfileHandler: await self._update_join_states(requester, target_user) - async def check_avatar_size_and_mime_type(self, mxc: str) -> None: - """Check that the size and content type of the avatar at the given MXC URI are - within the configured limits. - - Args: - mxc: The MXC URI at which the avatar can be found. - - Raises: - SynapseError with an M_FORBIDDEN error code if the avatar doesn't fit within - the limits allowed by the configuration. - """ - if not await self._check_avatar_size_and_mime_type(mxc): - raise SynapseError(403, "This avatar is not allowed", Codes.FORBIDDEN) - @cached() - async def _check_avatar_size_and_mime_type(self, mxc: str) -> bool: + async def check_avatar_size_and_mime_type(self, mxc: str) -> bool: """Check that the size and content type of the avatar at the given MXC URI are within the configured limits. @@ -365,9 +352,10 @@ class ProfileHandler: # Ensure avatar does not exceed max allowed avatar size if media_info["media_length"] > self.max_avatar_size: logger.warning( - "Forbidding avatar change to %s: avatar must be less than %s bytes", + "Forbidding avatar change to %s: %d bytes is above the allowed size " + "limit", mxc, - self.max_avatar_size, + media_info["media_length"], ) return False diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py index 4e979dd8e2..3dd5e1b6e4 100644 --- a/synapse/handlers/room_member.py +++ b/synapse/handlers/room_member.py @@ -591,9 +591,10 @@ class RoomMemberHandler(metaclass=abc.ABCMeta): ) if "avatar_url" in content: - await self.profile_handler.check_avatar_size_and_mime_type( - content["avatar_url"] - ) + if not await self.profile_handler.check_avatar_size_and_mime_type( + content["avatar_url"], + ): + raise SynapseError(403, "This avatar is not allowed", Codes.FORBIDDEN) # The event content should *not* include the authorising user as # it won't be properly signed. Strip it out since it might come diff --git a/tests/handlers/test_profile.py b/tests/handlers/test_profile.py index b7d6187a21..60235e5699 100644 --- a/tests/handlers/test_profile.py +++ b/tests/handlers/test_profile.py @@ -257,30 +257,22 @@ class ProfileTestCase(unittest.HomeserverTestCase): # The first check that's done by this method is whether the file exists; if we # don't get an error on a non-existing file then it means all of the checks were # successfully skipped. - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/unknown_file") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/unknown_file") ) - self.assertTrue(allowed) + self.assertTrue(res) - @unittest.override_config( - { - "max_avatar_size": 50, - } - ) + @unittest.override_config({"max_avatar_size": 50}) def test_avatar_constraints_missing(self): """Tests that an avatar isn't allowed if the file at the given MXC URI couldn't be found. """ - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/unknown_file") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/unknown_file") ) - self.assertFalse(allowed) + self.assertFalse(res) - @unittest.override_config( - { - "max_avatar_size": 50, - } - ) + @unittest.override_config({"max_avatar_size": 50}) def test_avatar_constraints_file_size(self): """Tests that a file that's above the allowed file size is forbidden but one that's below it is allowed. @@ -292,21 +284,17 @@ class ProfileTestCase(unittest.HomeserverTestCase): } ) - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/small") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/small") ) - self.assertTrue(allowed) + self.assertTrue(res) - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/big") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/big") ) - self.assertFalse(allowed) + self.assertFalse(res) - @unittest.override_config( - { - "allowed_avatar_mimetypes": ["image/png"], - } - ) + @unittest.override_config({"allowed_avatar_mimetypes": ["image/png"]}) def test_avatar_constraint_mime_type(self): """Tests that a file with an unauthorised MIME type is forbidden but one with an authorised content type is allowed. @@ -318,15 +306,15 @@ class ProfileTestCase(unittest.HomeserverTestCase): } ) - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/good") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/good") ) - self.assertTrue(allowed) + self.assertTrue(res) - allowed = self.get_success( - self.handler._check_avatar_size_and_mime_type("mxc://test/bad") + res = self.get_success( + self.handler.check_avatar_size_and_mime_type("mxc://test/bad") ) - self.assertFalse(allowed) + self.assertFalse(res) def _setup_local_files(self, names_and_props: Dict[str, Dict[str, Any]]): """Stores metadata about files in the database. diff --git a/tests/rest/client/test_profile.py b/tests/rest/client/test_profile.py index 140e62a46a..ead883ded8 100644 --- a/tests/rest/client/test_profile.py +++ b/tests/rest/client/test_profile.py @@ -155,11 +155,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): self.assertEqual(channel.code, 200, channel.result) return channel.json_body.get("avatar_url") - @unittest.override_config( - { - "max_avatar_size": 50, - } - ) + @unittest.override_config({"max_avatar_size": 50}) def test_avatar_size_limit_global(self): """Tests that the maximum size limit for avatars is enforced when updating a global profile. @@ -173,7 +169,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/profile/%s/avatar_url" % (self.owner,), + f"/profile/{self.owner}/avatar_url", content={"avatar_url": "mxc://test/big"}, access_token=self.owner_tok, ) @@ -184,17 +180,13 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/profile/%s/avatar_url" % (self.owner,), + f"/profile/{self.owner}/avatar_url", content={"avatar_url": "mxc://test/small"}, access_token=self.owner_tok, ) self.assertEqual(channel.code, 200, channel.result) - @unittest.override_config( - { - "max_avatar_size": 50, - } - ) + @unittest.override_config({"max_avatar_size": 50}) def test_avatar_size_limit_per_room(self): """Tests that the maximum size limit for avatars is enforced when updating a per-room profile. @@ -210,7 +202,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/rooms/%s/state/m.room.member/%s" % (room_id, self.owner), + f"/rooms/{room_id}/state/m.room.member/{self.owner}", content={"membership": "join", "avatar_url": "mxc://test/big"}, access_token=self.owner_tok, ) @@ -221,17 +213,13 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/rooms/%s/state/m.room.member/%s" % (room_id, self.owner), + f"/rooms/{room_id}/state/m.room.member/{self.owner}", content={"membership": "join", "avatar_url": "mxc://test/small"}, access_token=self.owner_tok, ) self.assertEqual(channel.code, 200, channel.result) - @unittest.override_config( - { - "allowed_avatar_mimetypes": ["image/png"], - } - ) + @unittest.override_config({"allowed_avatar_mimetypes": ["image/png"]}) def test_avatar_allowed_mime_type_global(self): """Tests that the MIME type whitelist for avatars is enforced when updating a global profile. @@ -245,7 +233,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/profile/%s/avatar_url" % (self.owner,), + f"/profile/{self.owner}/avatar_url", content={"avatar_url": "mxc://test/bad"}, access_token=self.owner_tok, ) @@ -256,17 +244,13 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/profile/%s/avatar_url" % (self.owner,), + f"/profile/{self.owner}/avatar_url", content={"avatar_url": "mxc://test/good"}, access_token=self.owner_tok, ) self.assertEqual(channel.code, 200, channel.result) - @unittest.override_config( - { - "allowed_avatar_mimetypes": ["image/png"], - } - ) + @unittest.override_config({"allowed_avatar_mimetypes": ["image/png"]}) def test_avatar_allowed_mime_type_per_room(self): """Tests that the MIME type whitelist for avatars is enforced when updating a per-room profile. @@ -282,7 +266,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/rooms/%s/state/m.room.member/%s" % (room_id, self.owner), + f"/rooms/{room_id}/state/m.room.member/{self.owner}", content={"membership": "join", "avatar_url": "mxc://test/bad"}, access_token=self.owner_tok, ) @@ -293,7 +277,7 @@ class ProfileTestCase(unittest.HomeserverTestCase): channel = self.make_request( "PUT", - "/rooms/%s/state/m.room.member/%s" % (room_id, self.owner), + f"/rooms/{room_id}/state/m.room.member/{self.owner}", content={"membership": "join", "avatar_url": "mxc://test/good"}, access_token=self.owner_tok, ) |