forked from MirrorHub/synapse
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:
parent
6abb1ad0be
commit
e4676bd877
5 changed files with 138 additions and 9 deletions
1
changelog.d/8722.feature
Normal file
1
changelog.d/8722.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add `displayname` to Shared-Secret Registration for admins.
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue