diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index 776ed43f03..c63d068f74 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -731,8 +731,11 @@ class MatrixFederationHttpClient:
Returns:
A list of headers to be added as "Authorization:" headers
"""
- if destination is None and destination_is is None:
- raise ValueError("destination and destination_is cannot both be None!")
+ if not destination and not destination_is:
+ raise ValueError(
+ "At least one of the arguments destination and destination_is "
+ "must be a nonempty bytestring."
+ )
request: JsonDict = {
"method": method.decode("ascii"),
diff --git a/synapse/rest/client/profile.py b/synapse/rest/client/profile.py
index c684636c0a..c16d707909 100644
--- a/synapse/rest/client/profile.py
+++ b/synapse/rest/client/profile.py
@@ -13,7 +13,7 @@
# limitations under the License.
""" This module contains REST servlets to do with profile: /profile/<paths> """
-
+from http import HTTPStatus
from typing import TYPE_CHECKING, Tuple
from synapse.api.errors import Codes, SynapseError
@@ -45,8 +45,12 @@ class ProfileDisplaynameRestServlet(RestServlet):
requester = await self.auth.get_user_by_req(request)
requester_user = requester.user
- user = UserID.from_string(user_id)
+ if not UserID.is_valid(user_id):
+ raise SynapseError(
+ HTTPStatus.BAD_REQUEST, "Invalid user id", Codes.INVALID_PARAM
+ )
+ user = UserID.from_string(user_id)
await self.profile_handler.check_profile_query_allowed(user, requester_user)
displayname = await self.profile_handler.get_displayname(user)
@@ -98,8 +102,12 @@ class ProfileAvatarURLRestServlet(RestServlet):
requester = await self.auth.get_user_by_req(request)
requester_user = requester.user
- user = UserID.from_string(user_id)
+ if not UserID.is_valid(user_id):
+ raise SynapseError(
+ HTTPStatus.BAD_REQUEST, "Invalid user id", Codes.INVALID_PARAM
+ )
+ user = UserID.from_string(user_id)
await self.profile_handler.check_profile_query_allowed(user, requester_user)
avatar_url = await self.profile_handler.get_avatar_url(user)
@@ -150,8 +158,12 @@ class ProfileRestServlet(RestServlet):
requester = await self.auth.get_user_by_req(request)
requester_user = requester.user
- user = UserID.from_string(user_id)
+ if not UserID.is_valid(user_id):
+ raise SynapseError(
+ HTTPStatus.BAD_REQUEST, "Invalid user id", Codes.INVALID_PARAM
+ )
+ user = UserID.from_string(user_id)
await self.profile_handler.check_profile_query_allowed(user, requester_user)
displayname = await self.profile_handler.get_displayname(user)
diff --git a/synapse/types.py b/synapse/types.py
index 0586d2cbb9..668d48d646 100644
--- a/synapse/types.py
+++ b/synapse/types.py
@@ -267,7 +267,6 @@ class DomainSpecificString(metaclass=abc.ABCMeta):
)
domain = parts[1]
-
# This code will need changing if we want to support multiple domain
# names on one HS
return cls(localpart=parts[0], domain=domain)
@@ -279,6 +278,8 @@ class DomainSpecificString(metaclass=abc.ABCMeta):
@classmethod
def is_valid(cls: Type[DS], s: str) -> bool:
"""Parses the input string and attempts to ensure it is valid."""
+ # TODO: this does not reject an empty localpart or an overly-long string.
+ # See https://spec.matrix.org/v1.2/appendices/#identifier-grammar
try:
obj = cls.from_string(s)
# Apply additional validation to the domain. This is only done
|