Prevent sending registration emails if registration is disabled (#19585)

This commit is contained in:
Andrew Morgan
2026-03-19 12:52:40 +00:00
committed by GitHub
parent f490c49c85
commit 9edbf56969
3 changed files with 49 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
Prevent sending registration emails if registration is disabled.
+9
View File
@@ -86,6 +86,7 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
self.server_name = hs.hostname
self.identity_handler = hs.get_identity_handler()
self.config = hs.config
self._registration_enabled = hs.config.registration.enable_registration
if self.hs.config.email.can_verify_email:
self.registration_mailer = Mailer(
@@ -109,6 +110,14 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
raise SynapseError(
400, "Email-based registration has been disabled on this server"
)
if not self._registration_enabled:
raise SynapseError(
403,
"Registration is disabled on this homeserver",
Codes.FORBIDDEN,
)
body = parse_json_object_from_request(request)
assert_params_in_dict(body, ["client_secret", "email", "send_attempt"])
+39 -1
View File
@@ -22,7 +22,7 @@
import datetime
import importlib.resources as importlib_resources
import os
from typing import Any
from typing import Any, cast
from unittest.mock import AsyncMock
from twisted.internet.testing import MemoryReactor
@@ -66,6 +66,17 @@ class RegisterRestServletTestCase(unittest.HomeserverTestCase):
hs.get_send_email_handler()._sendmail = AsyncMock()
return hs
def _get_sendmail_mock(self) -> AsyncMock:
"""
Cast the homeserver's `_sendmail` object as an `AsyncMock`.
`_sendmail` is an `AsyncMock` (see `make_homeserver`) but this type
information doesn't make it through the test harness. Thus we need to
cast the object again.
"""
sendmail = self.hs.get_send_email_handler()._sendmail
return cast(AsyncMock, sendmail)
def test_POST_appservice_registration_valid(self) -> None:
user_id = "@as_user_kermit:test"
as_token = "i_am_an_app_service"
@@ -747,6 +758,33 @@ class RegisterRestServletTestCase(unittest.HomeserverTestCase):
self.assertIsNotNone(channel.json_body.get("sid"))
@unittest.override_config(
{
"public_baseurl": "https://test_server",
"email": {
"smtp_host": "mail_server",
"smtp_port": 2525,
"notif_from": "sender@host",
},
}
)
def test_request_token_allowed_when_email_flow_is_advertised(self) -> None:
sendmail = self._get_sendmail_mock()
sendmail.reset_mock()
channel = self.make_request(
"POST",
b"register/email/requestToken",
{
"client_secret": "foobar",
"email": "test@example.com",
"send_attempt": 1,
},
)
self.assertEqual(200, channel.code, channel.result)
self.assertIsNotNone(channel.json_body.get("sid"))
sendmail.assert_awaited_once()
@unittest.override_config(
{
"public_baseurl": "https://test_server",