Add displayname to Shared-Secret Registration for admins (#8722)

Add `displayname` to Shared-Secret Registration for admins to `POST /_synapse/admin/v1/register`
This commit is contained in:
Dirk Klimpel 2020-11-05 14:55:45 +01:00 committed by GitHub
parent 6abb1ad0be
commit e4676bd877
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 138 additions and 9 deletions

1
changelog.d/8722.feature Normal file
View file

@ -0,0 +1 @@
Add `displayname` to Shared-Secret Registration for admins.

View file

@ -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 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 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:: As an example::
@ -26,6 +27,7 @@ As an example::
> { > {
"nonce": "thisisanonce", "nonce": "thisisanonce",
"username": "pepper_roni", "username": "pepper_roni",
"displayname": "Pepper Roni",
"password": "pizza", "password": "pizza",
"admin": true, "admin": true,
"mac": "mac_digest_here" "mac": "mac_digest_here"

View file

@ -412,6 +412,7 @@ class UserRegisterServlet(RestServlet):
admin = body.get("admin", None) admin = body.get("admin", None)
user_type = body.get("user_type", 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: if user_type is not None and user_type not in UserTypes.ALL_USER_TYPES:
raise SynapseError(400, "Invalid user type") raise SynapseError(400, "Invalid user type")
@ -448,6 +449,7 @@ class UserRegisterServlet(RestServlet):
password_hash=password_hash, password_hash=password_hash,
admin=bool(admin), admin=bool(admin),
user_type=user_type, user_type=user_type,
default_display_name=displayname,
by_admin=True, by_admin=True,
) )

View file

@ -24,7 +24,7 @@ from mock import Mock
import synapse.rest.admin import synapse.rest.admin
from synapse.api.constants import UserTypes from synapse.api.constants import UserTypes
from synapse.api.errors import Codes, HttpResponseException, ResourceLimitError 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 synapse.rest.client.v2_alpha import sync
from tests import unittest from tests import unittest
@ -34,7 +34,10 @@ from tests.unittest import override_config
class UserRegisterTestCase(unittest.HomeserverTestCase): 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): 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(400, int(channel.result["code"]), msg=channel.result["body"])
self.assertEqual("Invalid user type", channel.json_body["error"]) 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( @override_config(
{"limit_usage_by_mau": True, "max_mau_value": 2, "mau_trial_days": 0} {"limit_usage_by_mau": True, "max_mau_value": 2, "mau_trial_days": 0}
) )

View file

@ -546,18 +546,24 @@ class HomeserverTestCase(TestCase):
return result 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. Register a user. Requires the Admin API be registered.
Args: Args:
username (bytes/unicode): The user part of the new user. username: The user part of the new user.
password (bytes/unicode): The password of the new user. password: The password of the new user.
admin (bool): Whether the user should be created as an admin admin: Whether the user should be created as an admin or not.
or not. displayname: The displayname of the new user.
Returns: Returns:
The MXID of the new user (unicode). The MXID of the new user.
""" """
self.hs.config.registration_shared_secret = "shared" self.hs.config.registration_shared_secret = "shared"
@ -581,6 +587,7 @@ class HomeserverTestCase(TestCase):
{ {
"nonce": nonce, "nonce": nonce,
"username": username, "username": username,
"displayname": displayname,
"password": password, "password": password,
"admin": admin, "admin": admin,
"mac": want_mac, "mac": want_mac,