summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
Diffstat (limited to 'synapse')
-rw-r--r--synapse/groups/groups_server.py15
-rw-r--r--synapse/handlers/register.py10
-rw-r--r--synapse/types.py16
3 files changed, 25 insertions, 16 deletions
diff --git a/synapse/groups/groups_server.py b/synapse/groups/groups_server.py
index fc4edb7f04..c359bfa72b 100644
--- a/synapse/groups/groups_server.py
+++ b/synapse/groups/groups_server.py
@@ -13,14 +13,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from twisted.internet import defer
+import logging
 
+from synapse import types
 from synapse.api.errors import SynapseError
-from synapse.types import UserID, get_domain_from_id, RoomID, GroupID
-
-
-import logging
-import urllib
+from synapse.types import GroupID, RoomID, UserID, get_domain_from_id
+from twisted.internet import defer
 
 logger = logging.getLogger(__name__)
 
@@ -793,10 +791,7 @@ def _validate_group_id(group_id):
     """
     localpart = GroupID.from_string(group_id).localpart
 
-    if localpart.lower() != localpart:
-        raise SynapseError(400, "Group ID must be lower case")
-
-    if urllib.quote(localpart.encode('utf-8')) != localpart:
+    if types.contains_invalid_mxid_characters(localpart):
         raise SynapseError(
             400,
             "Group ID can only contain characters a-z, 0-9, or '_-./'",
diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py
index 560fb36254..c7c091f43e 100644
--- a/synapse/handlers/register.py
+++ b/synapse/handlers/register.py
@@ -15,7 +15,6 @@
 
 """Contains functions for registering clients."""
 import logging
-import urllib
 
 from twisted.internet import defer
 
@@ -23,6 +22,7 @@ from synapse.api.errors import (
     AuthError, Codes, SynapseError, RegistrationError, InvalidCaptchaError
 )
 from synapse.http.client import CaptchaServerHttpClient
+from synapse import types
 from synapse.types import UserID
 from synapse.util.async import run_on_reactor
 from ._base import BaseHandler
@@ -46,9 +46,7 @@ class RegistrationHandler(BaseHandler):
     @defer.inlineCallbacks
     def check_username(self, localpart, guest_access_token=None,
                        assigned_user_id=None):
-        yield run_on_reactor()
-
-        if urllib.quote(localpart.encode('utf-8')) != localpart:
+        if types.contains_invalid_mxid_characters(localpart):
             raise SynapseError(
                 400,
                 "User ID can only contain characters a-z, 0-9, or '_-./'",
@@ -81,7 +79,7 @@ class RegistrationHandler(BaseHandler):
                     "A different user ID has already been registered for this session",
                 )
 
-        yield self.check_user_id_not_appservice_exclusive(user_id)
+        self.check_user_id_not_appservice_exclusive(user_id)
 
         users = yield self.store.get_users_by_id_case_insensitive(user_id)
         if users:
@@ -254,7 +252,7 @@ class RegistrationHandler(BaseHandler):
         """
         Registers email_id as SAML2 Based Auth.
         """
-        if urllib.quote(localpart) != localpart:
+        if types.contains_invalid_mxid_characters(localpart):
             raise SynapseError(
                 400,
                 "User ID must only contain characters which do not"
diff --git a/synapse/types.py b/synapse/types.py
index 37d5fa7f9f..efa721273d 100644
--- a/synapse/types.py
+++ b/synapse/types.py
@@ -12,6 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import string
 
 from synapse.api.errors import SynapseError
 
@@ -161,6 +162,21 @@ class GroupID(DomainSpecificString):
     SIGIL = "+"
 
 
+mxid_localpart_allowed_characters = set("_-./" + string.ascii_lowercase + string.digits)
+
+
+def contains_invalid_mxid_characters(localpart):
+    """Check for characters not allowed in an mxid or groupid localpart
+
+    Args:
+        localpart (basestring): the localpart to be checked
+
+    Returns:
+        bool: True if there are any naughty characters
+    """
+    return any(c not in mxid_localpart_allowed_characters for c in localpart)
+
+
 class StreamToken(
     namedtuple("Token", (
         "room_key",