Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit e4676bd

Browse files
authored
Add displayname to Shared-Secret Registration for admins (#8722)
Add `displayname` to Shared-Secret Registration for admins to `POST /_synapse/admin/v1/register`
1 parent 6abb1ad commit e4676bd

File tree

5 files changed

+138
-9
lines changed

5 files changed

+138
-9
lines changed

changelog.d/8722.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `displayname` to Shared-Secret Registration for admins.

docs/admin_api/register_api.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ To fetch the nonce, you need to request one from the API::
1818

1919
Once you have the nonce, you can make a ``POST`` to the same URL with a JSON
2020
body containing the nonce, username, password, whether they are an admin
21-
(optional, False by default), and a HMAC digest of the content.
21+
(optional, False by default), and a HMAC digest of the content. Also you can
22+
set the displayname (optional, ``username`` by default).
2223

2324
As an example::
2425

2526
> POST /_synapse/admin/v1/register
2627
> {
2728
"nonce": "thisisanonce",
2829
"username": "pepper_roni",
30+
"displayname": "Pepper Roni",
2931
"password": "pizza",
3032
"admin": true,
3133
"mac": "mac_digest_here"

synapse/rest/admin/users.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ async def on_POST(self, request):
412412

413413
admin = body.get("admin", None)
414414
user_type = body.get("user_type", None)
415+
displayname = body.get("displayname", None)
415416

416417
if user_type is not None and user_type not in UserTypes.ALL_USER_TYPES:
417418
raise SynapseError(400, "Invalid user type")
@@ -448,6 +449,7 @@ async def on_POST(self, request):
448449
password_hash=password_hash,
449450
admin=bool(admin),
450451
user_type=user_type,
452+
default_display_name=displayname,
451453
by_admin=True,
452454
)
453455

tests/rest/admin/test_user.py

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import synapse.rest.admin
2525
from synapse.api.constants import UserTypes
2626
from synapse.api.errors import Codes, HttpResponseException, ResourceLimitError
27-
from synapse.rest.client.v1 import login, room
27+
from synapse.rest.client.v1 import login, profile, room
2828
from synapse.rest.client.v2_alpha import sync
2929

3030
from tests import unittest
@@ -34,7 +34,10 @@
3434

3535
class UserRegisterTestCase(unittest.HomeserverTestCase):
3636

37-
servlets = [synapse.rest.admin.register_servlets_for_client_rest_resource]
37+
servlets = [
38+
synapse.rest.admin.register_servlets_for_client_rest_resource,
39+
profile.register_servlets,
40+
]
3841

3942
def make_homeserver(self, reactor, clock):
4043

@@ -325,6 +328,120 @@ def nonce():
325328
self.assertEqual(400, int(channel.result["code"]), msg=channel.result["body"])
326329
self.assertEqual("Invalid user type", channel.json_body["error"])
327330

331+
def test_displayname(self):
332+
"""
333+
Test that displayname of new user is set
334+
"""
335+
336+
# set no displayname
337+
request, channel = self.make_request("GET", self.url)
338+
self.render(request)
339+
nonce = channel.json_body["nonce"]
340+
341+
want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
342+
want_mac.update(nonce.encode("ascii") + b"\x00bob1\x00abc123\x00notadmin")
343+
want_mac = want_mac.hexdigest()
344+
345+
body = json.dumps(
346+
{"nonce": nonce, "username": "bob1", "password": "abc123", "mac": want_mac}
347+
)
348+
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
349+
self.render(request)
350+
351+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
352+
self.assertEqual("@bob1:test", channel.json_body["user_id"])
353+
354+
request, channel = self.make_request("GET", "/profile/@bob1:test/displayname")
355+
self.render(request)
356+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
357+
self.assertEqual("bob1", channel.json_body["displayname"])
358+
359+
# displayname is None
360+
request, channel = self.make_request("GET", self.url)
361+
self.render(request)
362+
nonce = channel.json_body["nonce"]
363+
364+
want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
365+
want_mac.update(nonce.encode("ascii") + b"\x00bob2\x00abc123\x00notadmin")
366+
want_mac = want_mac.hexdigest()
367+
368+
body = json.dumps(
369+
{
370+
"nonce": nonce,
371+
"username": "bob2",
372+
"displayname": None,
373+
"password": "abc123",
374+
"mac": want_mac,
375+
}
376+
)
377+
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
378+
self.render(request)
379+
380+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
381+
self.assertEqual("@bob2:test", channel.json_body["user_id"])
382+
383+
request, channel = self.make_request("GET", "/profile/@bob2:test/displayname")
384+
self.render(request)
385+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
386+
self.assertEqual("bob2", channel.json_body["displayname"])
387+
388+
# displayname is empty
389+
request, channel = self.make_request("GET", self.url)
390+
self.render(request)
391+
nonce = channel.json_body["nonce"]
392+
393+
want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
394+
want_mac.update(nonce.encode("ascii") + b"\x00bob3\x00abc123\x00notadmin")
395+
want_mac = want_mac.hexdigest()
396+
397+
body = json.dumps(
398+
{
399+
"nonce": nonce,
400+
"username": "bob3",
401+
"displayname": "",
402+
"password": "abc123",
403+
"mac": want_mac,
404+
}
405+
)
406+
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
407+
self.render(request)
408+
409+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
410+
self.assertEqual("@bob3:test", channel.json_body["user_id"])
411+
412+
request, channel = self.make_request("GET", "/profile/@bob3:test/displayname")
413+
self.render(request)
414+
self.assertEqual(404, int(channel.result["code"]), msg=channel.result["body"])
415+
416+
# set displayname
417+
request, channel = self.make_request("GET", self.url)
418+
self.render(request)
419+
nonce = channel.json_body["nonce"]
420+
421+
want_mac = hmac.new(key=b"shared", digestmod=hashlib.sha1)
422+
want_mac.update(nonce.encode("ascii") + b"\x00bob4\x00abc123\x00notadmin")
423+
want_mac = want_mac.hexdigest()
424+
425+
body = json.dumps(
426+
{
427+
"nonce": nonce,
428+
"username": "bob4",
429+
"displayname": "Bob's Name",
430+
"password": "abc123",
431+
"mac": want_mac,
432+
}
433+
)
434+
request, channel = self.make_request("POST", self.url, body.encode("utf8"))
435+
self.render(request)
436+
437+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
438+
self.assertEqual("@bob4:test", channel.json_body["user_id"])
439+
440+
request, channel = self.make_request("GET", "/profile/@bob4:test/displayname")
441+
self.render(request)
442+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
443+
self.assertEqual("Bob's Name", channel.json_body["displayname"])
444+
328445
@override_config(
329446
{"limit_usage_by_mau": True, "max_mau_value": 2, "mau_trial_days": 0}
330447
)

tests/unittest.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -546,18 +546,24 @@ def get_success_or_raise(self, d, by=0.0):
546546

547547
return result
548548

549-
def register_user(self, username, password, admin=False):
549+
def register_user(
550+
self,
551+
username: str,
552+
password: str,
553+
admin: Optional[bool] = False,
554+
displayname: Optional[str] = None,
555+
) -> str:
550556
"""
551557
Register a user. Requires the Admin API be registered.
552558
553559
Args:
554-
username (bytes/unicode): The user part of the new user.
555-
password (bytes/unicode): The password of the new user.
556-
admin (bool): Whether the user should be created as an admin
557-
or not.
560+
username: The user part of the new user.
561+
password: The password of the new user.
562+
admin: Whether the user should be created as an admin or not.
563+
displayname: The displayname of the new user.
558564
559565
Returns:
560-
The MXID of the new user (unicode).
566+
The MXID of the new user.
561567
"""
562568
self.hs.config.registration_shared_secret = "shared"
563569

@@ -581,6 +587,7 @@ def register_user(self, username, password, admin=False):
581587
{
582588
"nonce": nonce,
583589
"username": username,
590+
"displayname": displayname,
584591
"password": password,
585592
"admin": admin,
586593
"mac": want_mac,

0 commit comments

Comments
 (0)