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

Commit 98fb610

Browse files
authored
Revert "Drop support for delegating email validation (matrix-org#13192)" (matrix-org#13406)
Reverts commit fa71bb1, and tweaks documentation. Signed-off-by: 3nprob <[email protected]>
1 parent 33788a0 commit 98fb610

File tree

12 files changed

+425
-266
lines changed

12 files changed

+425
-266
lines changed

changelog.d/13406.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warn instead of error when using `account_threepid_delegates.email`, which was deprecated in 1.64.0rc1.

docs/upgrade.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,6 @@ process, for example:
9191
9292
# Upgrading to v1.64.0
9393
94-
## Delegation of email validation no longer supported
95-
96-
As of this version, Synapse no longer allows the tasks of verifying email address
97-
ownership, and password reset confirmation, to be delegated to an identity server.
98-
99-
To continue to allow users to add email addresses to their homeserver accounts,
100-
and perform password resets, make sure that Synapse is configured with a
101-
working email server in the `email` configuration section (including, at a
102-
minimum, a `notif_from` setting.)
103-
104-
Specifying an `email` setting under `account_threepid_delegates` will now cause
105-
an error at startup.
106-
10794
## Changes to the event replication streams
10895
10996
Synapse now includes a flag indicating if an event is an outlier when

docs/usage/configuration/config_documentation.md

Lines changed: 181 additions & 181 deletions
Large diffs are not rendered by default.

synapse/app/homeserver.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
register_start,
4545
)
4646
from synapse.config._base import ConfigError, format_config_error
47+
from synapse.config.emailconfig import ThreepidBehaviour
4748
from synapse.config.homeserver import HomeServerConfig
4849
from synapse.config.server import ListenerConfig
4950
from synapse.federation.transport.server import TransportLayerServer
@@ -201,7 +202,7 @@ def _configure_named_resource(
201202
}
202203
)
203204

204-
if self.config.email.can_verify_email:
205+
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
205206
from synapse.rest.synapse.client.password_reset import (
206207
PasswordResetSubmitTokenResource,
207208
)

synapse/config/emailconfig.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import email.utils
1919
import logging
2020
import os
21+
from enum import Enum
2122
from typing import Any
2223

2324
import attr
@@ -135,22 +136,40 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
135136

136137
self.email_enable_notifs = email_config.get("enable_notifs", False)
137138

139+
self.threepid_behaviour_email = (
140+
# Have Synapse handle the email sending if account_threepid_delegates.email
141+
# is not defined
142+
# msisdn is currently always remote while Synapse does not support any method of
143+
# sending SMS messages
144+
ThreepidBehaviour.REMOTE
145+
if self.root.registration.account_threepid_delegate_email
146+
else ThreepidBehaviour.LOCAL
147+
)
148+
138149
if config.get("trust_identity_server_for_password_resets"):
139150
raise ConfigError(
140-
'The config option "trust_identity_server_for_password_resets" '
141-
"is no longer supported. Please remove it from the config file."
151+
'The config option "trust_identity_server_for_password_resets" has been removed.'
152+
"Please consult the configuration manual at docs/usage/configuration/config_documentation.md for "
153+
"details and update your config file."
142154
)
143155

144-
# If we have email config settings, assume that we can verify ownership of
145-
# email addresses.
146-
self.can_verify_email = email_config != {}
156+
self.local_threepid_handling_disabled_due_to_email_config = False
157+
if (
158+
self.threepid_behaviour_email == ThreepidBehaviour.LOCAL
159+
and email_config == {}
160+
):
161+
# We cannot warn the user this has happened here
162+
# Instead do so when a user attempts to reset their password
163+
self.local_threepid_handling_disabled_due_to_email_config = True
164+
165+
self.threepid_behaviour_email = ThreepidBehaviour.OFF
147166

148167
# Get lifetime of a validation token in milliseconds
149168
self.email_validation_token_lifetime = self.parse_duration(
150169
email_config.get("validation_token_lifetime", "1h")
151170
)
152171

153-
if self.can_verify_email:
172+
if self.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
154173
missing = []
155174
if not self.email_notif_from:
156175
missing.append("email.notif_from")
@@ -341,3 +360,18 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
341360
"Config option email.invite_client_location must be a http or https URL",
342361
path=("email", "invite_client_location"),
343362
)
363+
364+
365+
class ThreepidBehaviour(Enum):
366+
"""
367+
Enum to define the behaviour of Synapse with regards to when it contacts an identity
368+
server for 3pid registration and password resets
369+
370+
REMOTE = use an external server to send tokens
371+
LOCAL = send tokens ourselves
372+
OFF = disable registration via 3pid and password resets
373+
"""
374+
375+
REMOTE = "remote"
376+
LOCAL = "local"
377+
OFF = "off"

synapse/config/registration.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,23 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
import argparse
16+
import logging
1617
from typing import Any, Optional
1718

1819
from synapse.api.constants import RoomCreationPreset
1920
from synapse.config._base import Config, ConfigError
2021
from synapse.types import JsonDict, RoomAlias, UserID
2122
from synapse.util.stringutils import random_string_with_symbols, strtobool
2223

23-
NO_EMAIL_DELEGATE_ERROR = """\
24-
Delegation of email verification to an identity server is no longer supported. To
24+
logger = logging.getLogger(__name__)
25+
26+
LEGACY_EMAIL_DELEGATE_WARNING = """\
27+
Delegation of email verification to an identity server is now deprecated. To
2528
continue to allow users to add email addresses to their accounts, and use them for
2629
password resets, configure Synapse with an SMTP server via the `email` setting, and
2730
remove `account_threepid_delegates.email`.
31+
32+
This will be an error in a future version.
2833
"""
2934

3035

@@ -59,8 +64,9 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
5964

6065
account_threepid_delegates = config.get("account_threepid_delegates") or {}
6166
if "email" in account_threepid_delegates:
62-
raise ConfigError(NO_EMAIL_DELEGATE_ERROR)
63-
# self.account_threepid_delegate_email = account_threepid_delegates.get("email")
67+
logger.warning(LEGACY_EMAIL_DELEGATE_WARNING)
68+
69+
self.account_threepid_delegate_email = account_threepid_delegates.get("email")
6470
self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
6571
self.default_identity_server = config.get("default_identity_server")
6672
self.allow_guest_access = config.get("allow_guest_access", False)

synapse/handlers/identity.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
SynapseError,
2727
)
2828
from synapse.api.ratelimiting import Ratelimiter
29+
from synapse.config.emailconfig import ThreepidBehaviour
2930
from synapse.http import RequestTimedOutError
3031
from synapse.http.client import SimpleHttpClient
3132
from synapse.http.site import SynapseRequest
@@ -415,6 +416,48 @@ async def send_threepid_validation(
415416

416417
return session_id
417418

419+
async def request_email_token(
420+
self,
421+
id_server: str,
422+
email: str,
423+
client_secret: str,
424+
send_attempt: int,
425+
next_link: Optional[str] = None,
426+
) -> JsonDict:
427+
"""
428+
Request an external server send an email on our behalf for the purposes of threepid
429+
validation.
430+
431+
Args:
432+
id_server: The identity server to proxy to
433+
email: The email to send the message to
434+
client_secret: The unique client_secret sends by the user
435+
send_attempt: Which attempt this is
436+
next_link: A link to redirect the user to once they submit the token
437+
438+
Returns:
439+
The json response body from the server
440+
"""
441+
params = {
442+
"email": email,
443+
"client_secret": client_secret,
444+
"send_attempt": send_attempt,
445+
}
446+
if next_link:
447+
params["next_link"] = next_link
448+
449+
try:
450+
data = await self.http_client.post_json_get_json(
451+
id_server + "/_matrix/identity/api/v1/validate/email/requestToken",
452+
params,
453+
)
454+
return data
455+
except HttpResponseException as e:
456+
logger.info("Proxied requestToken failed: %r", e)
457+
raise e.to_synapse_error()
458+
except RequestTimedOutError:
459+
raise SynapseError(500, "Timed out contacting identity server")
460+
418461
async def requestMsisdnToken(
419462
self,
420463
id_server: str,
@@ -488,7 +531,18 @@ async def validate_threepid_session(
488531
validation_session = None
489532

490533
# Try to validate as email
491-
if self.hs.config.email.can_verify_email:
534+
if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
535+
# Remote emails will only be used if a valid identity server is provided.
536+
assert (
537+
self.hs.config.registration.account_threepid_delegate_email is not None
538+
)
539+
540+
# Ask our delegated email identity server
541+
validation_session = await self.threepid_from_creds(
542+
self.hs.config.registration.account_threepid_delegate_email,
543+
threepid_creds,
544+
)
545+
elif self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
492546
# Get a validated session matching these details
493547
validation_session = await self.store.get_threepid_validation_session(
494548
"email", client_secret, sid=sid, validated=True

synapse/handlers/ui_auth/checkers.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from synapse.api.constants import LoginType
2121
from synapse.api.errors import Codes, LoginError, SynapseError
22+
from synapse.config.emailconfig import ThreepidBehaviour
2223
from synapse.util import json_decoder
2324

2425
if TYPE_CHECKING:
@@ -152,7 +153,7 @@ async def _check_threepid(self, medium: str, authdict: dict) -> dict:
152153

153154
logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
154155

155-
# msisdns are currently always verified via the IS
156+
# msisdns are currently always ThreepidBehaviour.REMOTE
156157
if medium == "msisdn":
157158
if not self.hs.config.registration.account_threepid_delegate_msisdn:
158159
raise SynapseError(
@@ -163,7 +164,18 @@ async def _check_threepid(self, medium: str, authdict: dict) -> dict:
163164
threepid_creds,
164165
)
165166
elif medium == "email":
166-
if self.hs.config.email.can_verify_email:
167+
if (
168+
self.hs.config.email.threepid_behaviour_email
169+
== ThreepidBehaviour.REMOTE
170+
):
171+
assert self.hs.config.registration.account_threepid_delegate_email
172+
threepid = await identity_handler.threepid_from_creds(
173+
self.hs.config.registration.account_threepid_delegate_email,
174+
threepid_creds,
175+
)
176+
elif (
177+
self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL
178+
):
167179
threepid = None
168180
row = await self.store.get_threepid_validation_session(
169181
medium,
@@ -215,7 +227,10 @@ def __init__(self, hs: "HomeServer"):
215227
_BaseThreepidAuthChecker.__init__(self, hs)
216228

217229
def is_enabled(self) -> bool:
218-
return self.hs.config.email.can_verify_email
230+
return self.hs.config.email.threepid_behaviour_email in (
231+
ThreepidBehaviour.REMOTE,
232+
ThreepidBehaviour.LOCAL,
233+
)
219234

220235
async def check_auth(self, authdict: dict, clientip: str) -> Any:
221236
return await self._check_threepid("email", authdict)

0 commit comments

Comments
 (0)