diff --git a/changelog.d/14.feature b/changelog.d/14.feature
new file mode 100644
index 0000000000..020d0bac1e
--- /dev/null
+++ b/changelog.d/14.feature
@@ -0,0 +1 @@
+User displaynames now have capitalised letters after - symbols.
\ No newline at end of file
diff --git a/synapse/rest/client/v2_alpha/register.py b/synapse/rest/client/v2_alpha/register.py
index 0958a7fc58..dade6530f4 100644
--- a/synapse/rest/client/v2_alpha/register.py
+++ b/synapse/rest/client/v2_alpha/register.py
@@ -19,7 +19,6 @@ import hmac
import logging
import re
from hashlib import sha1
-from string import capwords
from six import string_types
@@ -486,21 +485,8 @@ class RegisterRestServlet(RestServlet):
if self.hs.config.register_just_use_email_for_display_name:
desired_display_name = address
else:
- # XXX: a nasty heuristic to turn an email address into
- # a displayname, as part of register_mxid_from_3pid
- parts = address.replace('.', ' ').split('@')
- org_parts = parts[1].split(' ')
-
- if org_parts[-2] == "matrix" and org_parts[-1] == "org":
- org = "Tchap Admin"
- elif org_parts[-2] == "gouv" and org_parts[-1] == "fr":
- org = org_parts[-3] if len(org_parts) > 2 else org_parts[-2]
- else:
- org = org_parts[-2]
-
- desired_display_name = (
- capwords(parts[0]) + " [" + capwords(org) + "]"
- )
+ # Custom mapping between email address and display name
+ desired_display_name = self._map_email_to_displayname(address)
elif (
self.hs.config.register_mxid_from_3pid == 'msisdn' and
LoginType.MSISDN in auth_result
@@ -743,6 +729,62 @@ class RegisterRestServlet(RestServlet):
}))
+def cap(name):
+ """Capitalise parts of a name containing different words, including those
+ separated by hyphens.
+ For example, 'John-Doe'
+
+ Args:
+ name (str): The name to parse
+ """
+ if not name:
+ return name
+
+ # Split the name by whitespace then hyphens, capitalizing each part then
+ # joining it back together.
+ capatilized_name = " ".join(
+ "-".join(part.capitalize() for part in space_part.split("-"))
+ for space_part in name.split()
+ )
+ return capatilized_name
+
+
+def _map_email_to_displayname(address):
+ """Custom mapping from an email address to a user displayname
+
+ Args:
+ address (str): The email address to process
+ Returns:
+ str: The new displayname
+ """
+ # Split the part before and after the @ in the email.
+ # Replace all . with spaces in the first part
+ parts = address.replace('.', ' ').split('@')
+
+ # Figure out which org this email address belongs to
+ org_parts = parts[1].split(' ')
+
+ # If this is a ...matrix.org email, mark them as an Admin
+ if org_parts[-2] == "matrix" and org_parts[-1] == "org":
+ org = "Tchap Admin"
+
+ # Is this is a ...gouv.fr address, set the org to whatever is before
+ # gouv.fr. If there isn't anything (a @gouv.fr email) simply mark their
+ # org as "gouv"
+ elif org_parts[-2] == "gouv" and org_parts[-1] == "fr":
+ org = org_parts[-3] if len(org_parts) > 2 else org_parts[-2]
+
+ # Otherwise, mark their org as the email's second-level domain name
+ else:
+ org = org_parts[-2]
+
+ desired_display_name = (
+ cap(parts[0]) + " [" + cap(org) + "]"
+ )
+
+ return desired_display_name
+
+
def register_servlets(hs, http_server):
EmailRegisterRequestTokenRestServlet(hs).register(http_server)
MsisdnRegisterRequestTokenRestServlet(hs).register(http_server)
diff --git a/tests/handlers/test_register.py b/tests/handlers/test_register.py
index 5ffba2ca7a..b2aa5c2478 100644
--- a/tests/handlers/test_register.py
+++ b/tests/handlers/test_register.py
@@ -20,6 +20,7 @@ from twisted.internet import defer
from synapse.api.constants import UserTypes
from synapse.api.errors import ResourceLimitError, SynapseError
from synapse.handlers.register import RegistrationHandler
+from synapse.rest.client.v2_alpha.register import _map_email_to_displayname
from synapse.types import RoomAlias, UserID, create_requester
from .. import unittest
@@ -235,3 +236,30 @@ class RegistrationTestCase(unittest.HomeserverTestCase):
self.handler.register(localpart=invalid_user_id),
SynapseError
)
+
+ def test_email_to_displayname_mapping(self):
+ """Test that custom emails are mapped to new user displaynames correctly"""
+ self._check_mapping(
+ "jack-phillips.rivers@big-org.com",
+ "Jack-Phillips Rivers [Big-Org]",
+ )
+
+ self._check_mapping(
+ "bob.jones@matrix.org",
+ "Bob Jones [Tchap Admin]",
+ )
+
+ self._check_mapping(
+ "bob-jones.blabla@gouv.fr",
+ "Bob-Jones Blabla [Gouv]",
+ )
+
+ # Multibyte unicode characters
+ self._check_mapping(
+ u"j\u030a\u0065an-poppy.seed@example.com",
+ u"J\u030a\u0065an-Poppy Seed [Example]",
+ )
+
+ def _check_mapping(self, i, expected):
+ result = _map_email_to_displayname(i)
+ self.assertEqual(result, expected)
|