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

Commit

Permalink
Merge pull request #5309 from matrix-org/rav/limit_displayname_length
Browse files Browse the repository at this point in the history
Limit displaynames and avatar URLs
  • Loading branch information
richvdh authored Jun 1, 2019
2 parents 37b1656 + 93003aa commit d828d1d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.d/5309.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prevent users from setting huge displaynames and avatar URLs.
13 changes: 13 additions & 0 deletions synapse/handlers/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@

logger = logging.getLogger(__name__)

MAX_DISPLAYNAME_LEN = 100
MAX_AVATAR_URL_LEN = 1000


class BaseProfileHandler(BaseHandler):
"""Handles fetching and updating user profile information.
Expand Down Expand Up @@ -162,6 +165,11 @@ def set_displayname(self, target_user, requester, new_displayname, by_admin=Fals
if not by_admin and target_user != requester.user:
raise AuthError(400, "Cannot set another user's displayname")

if len(new_displayname) > MAX_DISPLAYNAME_LEN:
raise SynapseError(
400, "Displayname is too long (max %i)" % (MAX_DISPLAYNAME_LEN, ),
)

if new_displayname == '':
new_displayname = None

Expand Down Expand Up @@ -217,6 +225,11 @@ def set_avatar_url(self, target_user, requester, new_avatar_url, by_admin=False)
if not by_admin and target_user != requester.user:
raise AuthError(400, "Cannot set another user's avatar_url")

if len(new_avatar_url) > MAX_AVATAR_URL_LEN:
raise SynapseError(
400, "Avatar URL is too long (max %i)" % (MAX_AVATAR_URL_LEN, ),
)

yield self.store.set_profile_avatar_url(
target_user.localpart, new_avatar_url
)
Expand Down
2 changes: 2 additions & 0 deletions synapse/handlers/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,8 @@ def get_or_create_user(self, requester, localpart, displayname,
A tuple of (user_id, access_token).
Raises:
RegistrationError if there was a problem registering.
NB this is only used in tests. TODO: move it to the test package!
"""
if localpart is None:
raise SynapseError(400, "Request must include user id")
Expand Down
62 changes: 60 additions & 2 deletions tests/rest/client/v1/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# limitations under the License.

"""Tests REST events for /profile paths."""
import json

from mock import Mock

from twisted.internet import defer
Expand All @@ -31,8 +33,11 @@
PATH_PREFIX = "/_matrix/client/api/v1"


class ProfileTestCase(unittest.TestCase):
""" Tests profile management. """
class MockHandlerProfileTestCase(unittest.TestCase):
""" Tests rest layer of profile management.
Todo: move these into ProfileTestCase
"""

@defer.inlineCallbacks
def setUp(self):
Expand Down Expand Up @@ -159,6 +164,59 @@ def test_set_my_avatar(self):
self.assertEquals(mocked_set.call_args[0][2], "http://my.server/pic.gif")


class ProfileTestCase(unittest.HomeserverTestCase):

servlets = [
admin.register_servlets_for_client_rest_resource,
login.register_servlets,
profile.register_servlets,
]

def make_homeserver(self, reactor, clock):
self.hs = self.setup_test_homeserver()
return self.hs

def prepare(self, reactor, clock, hs):
self.owner = self.register_user("owner", "pass")
self.owner_tok = self.login("owner", "pass")

def test_set_displayname(self):
request, channel = self.make_request(
"PUT",
"/profile/%s/displayname" % (self.owner, ),
content=json.dumps({"displayname": "test"}),
access_token=self.owner_tok,
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)

res = self.get_displayname()
self.assertEqual(res, "test")

def test_set_displayname_too_long(self):
"""Attempts to set a stupid displayname should get a 400"""
request, channel = self.make_request(
"PUT",
"/profile/%s/displayname" % (self.owner, ),
content=json.dumps({"displayname": "test" * 100}),
access_token=self.owner_tok,
)
self.render(request)
self.assertEqual(channel.code, 400, channel.result)

res = self.get_displayname()
self.assertEqual(res, "owner")

def get_displayname(self):
request, channel = self.make_request(
"GET",
"/profile/%s/displayname" % (self.owner, ),
)
self.render(request)
self.assertEqual(channel.code, 200, channel.result)
return channel.json_body["displayname"]


class ProfilesRestrictedTestCase(unittest.HomeserverTestCase):

servlets = [
Expand Down

0 comments on commit d828d1d

Please sign in to comment.