summary refs log tree commit diff
diff options
context:
space:
mode:
authorDirk Klimpel <5740567+dklimpel@users.noreply.github.com>2020-11-05 14:55:45 +0100
committerGitHub <noreply@github.com>2020-11-05 13:55:45 +0000
commite4676bd8772275833857c803f8fe4025744cec01 (patch)
treefc51c24cf327979a294a74922ff2205e39ac9df6
parentConsolidate purge table lists to prevent desyncronisation (#8713) (diff)
downloadsynapse-e4676bd8772275833857c803f8fe4025744cec01.tar.xz
Add `displayname` to Shared-Secret Registration for admins (#8722)
Add `displayname` to Shared-Secret Registration for admins to `POST /_synapse/admin/v1/register`
-rw-r--r--changelog.d/8722.feature1
-rw-r--r--docs/admin_api/register_api.rst4
-rw-r--r--synapse/rest/admin/users.py2
-rw-r--r--tests/rest/admin/test_user.py121
-rw-r--r--tests/unittest.py19
5 files changed, 138 insertions, 9 deletions
diff --git a/changelog.d/8722.feature b/changelog.d/8722.feature
new file mode 100644
index 0000000000..0413d8838b
--- /dev/null
+++ b/changelog.d/8722.feature
@@ -0,0 +1 @@
+Add `displayname` to Shared-Secret Registration for admins.
\ No newline at end of file
diff --git a/docs/admin_api/register_api.rst b/docs/admin_api/register_api.rst
index 3a63109aa0..c3057b204b 100644
--- a/docs/admin_api/register_api.rst
+++ b/docs/admin_api/register_api.rst
@@ -18,7 +18,8 @@ To fetch the nonce, you need to request one from the API::
 
 Once you have the nonce, you can make a ``POST`` to the same URL with a JSON
 body containing the nonce, username, password, whether they are an admin
-(optional, False by default), and a HMAC digest of the content.
+(optional, False by default), and a HMAC digest of the content. Also you can
+set the displayname (optional, ``username`` by default).
 
 As an example::
 
@@ -26,6 +27,7 @@ As an example::
   > {
      "nonce": "thisisanonce",
      "username": "pepper_roni",
+     "displayname": "Pepper Roni",
      "password": "pizza",
      "admin": true,
      "mac": "mac_digest_here"
diff --git a/synapse/rest/admin/users.py b/synapse/rest/admin/users.py
index b337311a37..3638e219f2 100644
--- a/synapse/rest/admin/users.py
+++ b/synapse/rest/admin/users.py
@@ -412,6 +412,7 @@ class UserRegisterServlet(RestServlet):
 
         admin = body.get("admin", None)
         user_type = body.get("user_type", None)
+        displayname = body.get("displayname", None)
 
         if user_type is not None and user_type not in UserTypes.ALL_USER_TYPES:
             raise SynapseError(400, "Invalid user type")
@@ -448,6 +449,7 @@ class UserRegisterServlet(RestServlet):
             password_hash=password_hash,
             admin=bool(admin),
             user_type=user_type,
+            default_display_name=displayname,
             by_admin=True,
         )
 
diff --git a/tests/rest/admin/test_user.py b/tests/rest/admin/test_user.py
index 7df32e5093..d74efede06 100644
--- a/tests/rest/admin/test_user.py
+++ b/tests/rest/admin/test_user.py
@@ -24,7 +24,7 @@ from mock import Mock
 import synapse.rest.admin
 from synapse.api.constants import UserTypes
 from synapse.api.errors import Codes, HttpResponseException, ResourceLimitError
-from synapse.rest.client.v1 import login, room
+from synapse.rest.client.v1 import login, profile, room
 from synapse.rest.client.v2_alpha import sync
 
 from tests import unittest
@@ -34,7 +34,10 @@ from tests.unittest import override_config
 
 class UserRegisterTestCase(unittest.HomeserverTestCase):
 
-    servlets = [synapse.rest.admin.register_servlets_for_client_rest_resource]
+    servlets = [
+        synapse.rest.admin.register_servlets_for_client_rest_resource,
+        profile.register_servlets,
+    ]
 
     def make_homeserver(self, reactor, clock):
 
@@ -325,6 +328,120 @@ class UserRegisterTestCase(unittest.HomeserverTestCase):
         self.assertEqual(400, int(channel.result["code"]), msg=channel.result["body"])
         self.assertEqual("Invalid user type", channel.json_body["error"])
 
+    def test_displayname(self):
+        """
+        Test that displayname of new user is set
+        """
+
+        # set no displayname
+        request, channel = self.make_request("GET", self.url)
+        self.render(request)
+        nonce = channel.json_body["nonce"]
+
+        want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
+        want_mac.update(nonce.encode("ascii") + b"\x00bob1\x00abc123\x00notadmin")
+        want_mac = want_mac.hexdigest()
+
+        body = json.dumps(
+            {"nonce": nonce, "username": "bob1", "password": "abc123", "mac": want_mac}
+        )
+        request, channel = self.make_request("POST", self.url, body.encode("utf8"))
+        self.render(request)
+
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("@bob1:test", channel.json_body["user_id"])
+
+        request, channel = self.make_request("GET", "/profile/@bob1:test/displayname")
+        self.render(request)
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("bob1", channel.json_body["displayname"])
+
+        # displayname is None
+        request, channel = self.make_request("GET", self.url)
+        self.render(request)
+        nonce = channel.json_body["nonce"]
+
+        want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
+        want_mac.update(nonce.encode("ascii") + b"\x00bob2\x00abc123\x00notadmin")
+        want_mac = want_mac.hexdigest()
+
+        body = json.dumps(
+            {
+                "nonce": nonce,
+                "username": "bob2",
+                "displayname": None,
+                "password": "abc123",
+                "mac": want_mac,
+            }
+        )
+        request, channel = self.make_request("POST", self.url, body.encode("utf8"))
+        self.render(request)
+
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("@bob2:test", channel.json_body["user_id"])
+
+        request, channel = self.make_request("GET", "/profile/@bob2:test/displayname")
+        self.render(request)
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("bob2", channel.json_body["displayname"])
+
+        # displayname is empty
+        request, channel = self.make_request("GET", self.url)
+        self.render(request)
+        nonce = channel.json_body["nonce"]
+
+        want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
+        want_mac.update(nonce.encode("ascii") + b"\x00bob3\x00abc123\x00notadmin")
+        want_mac = want_mac.hexdigest()
+
+        body = json.dumps(
+            {
+                "nonce": nonce,
+                "username": "bob3",
+                "displayname": "",
+                "password": "abc123",
+                "mac": want_mac,
+            }
+        )
+        request, channel = self.make_request("POST", self.url, body.encode("utf8"))
+        self.render(request)
+
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("@bob3:test", channel.json_body["user_id"])
+
+        request, channel = self.make_request("GET", "/profile/@bob3:test/displayname")
+        self.render(request)
+        self.assertEqual(404, int(channel.result["code"]), msg=channel.result["body"])
+
+        # set displayname
+        request, channel = self.make_request("GET", self.url)
+        self.render(request)
+        nonce = channel.json_body["nonce"]
+
+        want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
+        want_mac.update(nonce.encode("ascii") + b"\x00bob4\x00abc123\x00notadmin")
+        want_mac = want_mac.hexdigest()
+
+        body = json.dumps(
+            {
+                "nonce": nonce,
+                "username": "bob4",
+                "displayname": "Bob's Name",
+                "password": "abc123",
+                "mac": want_mac,
+            }
+        )
+        request, channel = self.make_request("POST", self.url, body.encode("utf8"))
+        self.render(request)
+
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("@bob4:test", channel.json_body["user_id"])
+
+        request, channel = self.make_request("GET", "/profile/@bob4:test/displayname")
+        self.render(request)
+        self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
+        self.assertEqual("Bob's Name", channel.json_body["displayname"])
+
     @override_config(
         {"limit_usage_by_mau": True, "max_mau_value": 2, "mau_trial_days": 0}
     )
diff --git a/tests/unittest.py b/tests/unittest.py
index 08cf9b10c5..e36ac89196 100644
--- a/tests/unittest.py
+++ b/tests/unittest.py
@@ -546,18 +546,24 @@ class HomeserverTestCase(TestCase):
 
         return result
 
-    def register_user(self, username, password, admin=False):
+    def register_user(
+        self,
+        username: str,
+        password: str,
+        admin: Optional[bool] = False,
+        displayname: Optional[str] = None,
+    ) -> str:
         """
         Register a user. Requires the Admin API be registered.
 
         Args:
-            username (bytes/unicode): The user part of the new user.
-            password (bytes/unicode): The password of the new user.
-            admin (bool): Whether the user should be created as an admin
-            or not.
+            username: The user part of the new user.
+            password: The password of the new user.
+            admin: Whether the user should be created as an admin or not.
+            displayname: The displayname of the new user.
 
         Returns:
-            The MXID of the new user (unicode).
+            The MXID of the new user.
         """
         self.hs.config.registration_shared_secret = "shared"
 
@@ -581,6 +587,7 @@ class HomeserverTestCase(TestCase):
             {
                 "nonce": nonce,
                 "username": username,
+                "displayname": displayname,
                 "password": password,
                 "admin": admin,
                 "mac": want_mac,