1 files changed, 33 insertions, 0 deletions
diff --git a/synapse/types.py b/synapse/types.py
index 1aa426fcbb..1eeda0b72f 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
@@ -156,6 +157,38 @@ class GroupID(DomainSpecificString):
"""Structure representing a group ID."""
SIGIL = "+"
+ @classmethod
+ def from_string(cls, s):
+ group_id = super(GroupID, cls).from_string(s)
+ if not group_id.localpart:
+ raise SynapseError(
+ 400,
+ "Group ID cannot be empty",
+ )
+
+ if contains_invalid_mxid_characters(group_id.localpart):
+ raise SynapseError(
+ 400,
+ "Group ID can only contain characters a-z, 0-9, or '=_-./'",
+ )
+
+ return group_id
+
+
+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", (
|