Skip to content

Commit 9edbf56

Browse files
Prevent sending registration emails if registration is disabled (#19585)
1 parent f490c49 commit 9edbf56

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

changelog.d/19585.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prevent sending registration emails if registration is disabled.

synapse/rest/client/register.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def __init__(self, hs: "HomeServer"):
8686
self.server_name = hs.hostname
8787
self.identity_handler = hs.get_identity_handler()
8888
self.config = hs.config
89+
self._registration_enabled = hs.config.registration.enable_registration
8990

9091
if self.hs.config.email.can_verify_email:
9192
self.registration_mailer = Mailer(
@@ -109,6 +110,14 @@ async def on_POST(self, request: SynapseRequest) -> tuple[int, JsonDict]:
109110
raise SynapseError(
110111
400, "Email-based registration has been disabled on this server"
111112
)
113+
114+
if not self._registration_enabled:
115+
raise SynapseError(
116+
403,
117+
"Registration is disabled on this homeserver",
118+
Codes.FORBIDDEN,
119+
)
120+
112121
body = parse_json_object_from_request(request)
113122

114123
assert_params_in_dict(body, ["client_secret", "email", "send_attempt"])

tests/rest/client/test_register.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import datetime
2323
import importlib.resources as importlib_resources
2424
import os
25-
from typing import Any
25+
from typing import Any, cast
2626
from unittest.mock import AsyncMock
2727

2828
from twisted.internet.testing import MemoryReactor
@@ -66,6 +66,17 @@ def make_homeserver(
6666
hs.get_send_email_handler()._sendmail = AsyncMock()
6767
return hs
6868

69+
def _get_sendmail_mock(self) -> AsyncMock:
70+
"""
71+
Cast the homeserver's `_sendmail` object as an `AsyncMock`.
72+
73+
`_sendmail` is an `AsyncMock` (see `make_homeserver`) but this type
74+
information doesn't make it through the test harness. Thus we need to
75+
cast the object again.
76+
"""
77+
sendmail = self.hs.get_send_email_handler()._sendmail
78+
return cast(AsyncMock, sendmail)
79+
6980
def test_POST_appservice_registration_valid(self) -> None:
7081
user_id = "@as_user_kermit:test"
7182
as_token = "i_am_an_app_service"
@@ -747,6 +758,33 @@ def test_request_token_existing_email_inhibit_error(self) -> None:
747758

748759
self.assertIsNotNone(channel.json_body.get("sid"))
749760

761+
@unittest.override_config(
762+
{
763+
"public_baseurl": "https://test_server",
764+
"email": {
765+
"smtp_host": "mail_server",
766+
"smtp_port": 2525,
767+
"notif_from": "sender@host",
768+
},
769+
}
770+
)
771+
def test_request_token_allowed_when_email_flow_is_advertised(self) -> None:
772+
sendmail = self._get_sendmail_mock()
773+
sendmail.reset_mock()
774+
775+
channel = self.make_request(
776+
"POST",
777+
b"register/email/requestToken",
778+
{
779+
"client_secret": "foobar",
780+
"email": "test@example.com",
781+
"send_attempt": 1,
782+
},
783+
)
784+
self.assertEqual(200, channel.code, channel.result)
785+
self.assertIsNotNone(channel.json_body.get("sid"))
786+
sendmail.assert_awaited_once()
787+
750788
@unittest.override_config(
751789
{
752790
"public_baseurl": "https://test_server",

0 commit comments

Comments
 (0)