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

Change account_threepid_delegate to a dictionary #5969

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions UPGRADE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,23 @@ its own, phone-based password resets and registration will be disabled. For Syna
emails, the ``email`` block of the config must be filled out. If not, then password resets and
registration via email will be disabled entirely.

This release also deprecates the ``email.trust_identity_server_for_password_resets`` option
and replaces it with ``account_threepid_delegate``. This option defines whether the homeserver
should delegate an external server (typically an `identity server
<https://matrix.org/docs/spec/identity_service/r0.2.1>`_) to handle sending password reset
or registration messages via email or SMS.

If ``email.trust_identity_server_for_password_resets`` was changed from its default to
``true``, and ``account_threepid_delegate`` is not set to an identity server domain, then the
server handling password resets and registration via third-party addresses will be set to the
first entry in the Synapse config's ``trusted_third_party_id_servers`` entry. If no domains are
configured, Synapse will throw an error on startup.

If ``email.trust_identity_server_for_password_resets`` is not set to ``true`` and
``account_threepid_delegate`` is not set to a domain, then Synapse will attempt to send
password reset and registration messages itself.
This release also deprecates the ``email.trust_identity_server_for_password_resets`` option and
replaces it with the ``account_threepid_delegates`` dictionary. This option defines whether the
homeserver should delegate an external server (typically an `identity server
<https://matrix.org/docs/spec/identity_service/r0.2.1>`_) to handle sending password reset or
registration messages via email and SMS.

Specifically for email, if ``email.trust_identity_server_for_password_resets`` was changed from
its default to ``true``, and ``account_threepid_delegates.email`` is not set, then the server
handling password resets and registration via third-party addresses will be set to the first
entry in the Synapse config's ``trusted_third_party_id_servers`` entry. This is to ensure that
people who set up an external server for handling these tasks before v1.4.0 will not have their
setups mysteriously stop working. However, if no trusted identity server domains are
configured, Synapse will throw an error.

If ``email.trust_identity_server_for_password_resets`` is not set to ``true`` and a type in
``account_threepid_delegates`` is not set to a domain, then Synapse will attempt to send
password reset and registration messages itself for that type.

Email templates
---------------
Expand Down
1 change: 1 addition & 0 deletions changelog.d/5969.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Change account_threepid_delegate to an account_threepid_delegates dictionary to handle the case of Synapse handling email verification, and an external server handling msisdn verification.
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
37 changes: 24 additions & 13 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -903,19 +903,30 @@ uploads_path: "DATADIR/uploads"
# - matrix.org
# - vector.im

# Handle threepid (email/phone etc) registration and password resets
# through a *trusted* identity server. Note that this allows the configured
# identity server to reset passwords for accounts.
#
# If this option is not defined and SMTP options have not been
# configured, registration by email and resetting user passwords via
# email will be disabled
#
# Otherwise, to enable set this option to the reachable domain name, including protocol
# definition, for an identity server
# (e.g "https://matrix.org", "http://localhost:8090")
#
#account_threepid_delegate: ""
# Handle threepid (email/phone etc) registration and password resets through a set of
# *trusted* identity servers. Note that this allows the configured identity server to
# reset passwords for accounts!
#
# Also be aware that if email is not set to a domain, and SMTP options have not been
# configured in the email config block, registration and resetting user passwords via
# email will be globally disabled.
#
# Additionally, if msisdn is not set to a domain, registration and password resets via
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# msisdn will be disabled regardless. This is due to Synapse currently not supporting
# any method of sending SMS messages on its own.
#
# To enable using an identity server for operations regarding a particular third-party
# identifier type, set the value to the reachable domain name of that identity server,
# including protocol definition, e.g:
# email: "https://matrix.org" # Let matrix.org handle sending emails for my users
# msisdn: "http://localhost:8090" # Delegate contacting SMS numbers to this process
#
# Servers handling the above requests must answer the .../requestToken endpoints
# defined by the Matrix Identity Service API specification:
# https://matrix.org/docs/spec/identity_service/latest
#account_threepid_delegates:
# email: ""
# msisdn: ""

# Users who register on this homeserver will automatically be joined
# to these rooms
Expand Down
27 changes: 17 additions & 10 deletions synapse/config/emailconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ def read_config(self, config, **kwargs):
"renew_at"
)

self.threepid_behaviour = (
# Have Synapse handle the email sending if account_threepid_delegate
self.threepid_behaviour_email = (
# Have Synapse handle the email sending if account_threepid_delegates.email
# is not defined
# msisdn is currently always remote while Synapse does not support any method of
# sending SMS messages
ThreepidBehaviour.REMOTE
if self.account_threepid_delegate
if self.account_threepid_delegate_email
else ThreepidBehaviour.LOCAL
)
# Prior to Synapse v1.4.0, there was another option that defined whether Synapse would
Expand All @@ -88,14 +90,16 @@ def read_config(self, config, **kwargs):
# identity server in the process.
self.using_identity_server_from_trusted_list = False
if (
not self.account_threepid_delegate
not self.account_threepid_delegate_email
and config.get("trust_identity_server_for_password_resets", False) is True
):
# Use the first entry in self.trusted_third_party_id_servers instead
if self.trusted_third_party_id_servers:
# XXX: It's a little confusing that account_threepid_delegate is modifed
# XXX: It's a little confusing that account_threepid_delegates is modified
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# both in RegistrationConfig and here. We should factor this bit out
self.account_threepid_delegate = self.trusted_third_party_id_servers[0]
self.account_threepid_delegate_email = self.trusted_third_party_id_servers[
0
]
self.using_identity_server_from_trusted_list = True
else:
raise ConfigError(
Expand All @@ -104,12 +108,15 @@ def read_config(self, config, **kwargs):
)

self.local_threepid_handling_disabled_due_to_email_config = False
if self.threepid_behaviour == ThreepidBehaviour.LOCAL and email_config == {}:
if (
self.threepid_behaviour_email == ThreepidBehaviour.LOCAL
and email_config == {}
):
# We cannot warn the user this has happened here
# Instead do so when a user attempts to reset their password
self.local_threepid_handling_disabled_due_to_email_config = True

self.threepid_behaviour = ThreepidBehaviour.OFF
self.threepid_behaviour_email = ThreepidBehaviour.OFF

# Get lifetime of a validation token in milliseconds
self.email_validation_token_lifetime = self.parse_duration(
Expand All @@ -119,7 +126,7 @@ def read_config(self, config, **kwargs):
if (
self.email_enable_notifs
or account_validity_renewal_enabled
or self.threepid_behaviour == ThreepidBehaviour.LOCAL
or self.threepid_behaviour_email == ThreepidBehaviour.LOCAL
):
# make sure we can import the required deps
import jinja2
Expand All @@ -129,7 +136,7 @@ def read_config(self, config, **kwargs):
jinja2
bleach

if self.threepid_behaviour == ThreepidBehaviour.LOCAL:
if self.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
required = ["smtp_host", "smtp_port", "notif_from"]

missing = []
Expand Down
45 changes: 34 additions & 11 deletions synapse/config/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,19 @@ def read_config(self, config, **kwargs):
self.trusted_third_party_id_servers = config.get(
"trusted_third_party_id_servers", ["matrix.org", "vector.im"]
)
self.account_threepid_delegate = config.get("account_threepid_delegate")
account_threepid_delegates = config.get(
"account_threepid_delegates", {"email": "", "msisdn": ""}
)
self.account_threepid_delegate_email = account_threepid_delegates.get("email")
self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
if (
self.account_threepid_delegate_email is None
or self.account_threepid_delegate_msisdn is None
):
raise ConfigError(
"account_threepid_delegates must contain fields: email, msisdn"
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
)

self.default_identity_server = config.get("default_identity_server")
self.allow_guest_access = config.get("allow_guest_access", False)

Expand Down Expand Up @@ -270,19 +282,30 @@ def generate_config_section(self, generate_secrets=False, **kwargs):
# - matrix.org
# - vector.im

# Handle threepid (email/phone etc) registration and password resets
# through a *trusted* identity server. Note that this allows the configured
# identity server to reset passwords for accounts.
# Handle threepid (email/phone etc) registration and password resets through a set of
# *trusted* identity servers. Note that this allows the configured identity server to
# reset passwords for accounts!
#
# Also be aware that if email is not set to a domain, and SMTP options have not been
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# configured in the email config block, registration and resetting user passwords via
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# email will be globally disabled.
#
# If this option is not defined and SMTP options have not been
# configured, registration by email and resetting user passwords via
# email will be disabled
# Additionally, if msisdn is not set to a domain, registration and password resets via
# msisdn will be disabled regardless. This is due to Synapse currently not supporting
# any method of sending SMS messages on its own.
#
# Otherwise, to enable set this option to the reachable domain name, including protocol
# definition, for an identity server
# (e.g "https://matrix.org", "http://localhost:8090")
# To enable using an identity server for operations regarding a particular third-party
# identifier type, set the value to the reachable domain name of that identity server,
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# including protocol definition, e.g:
# email: "https://matrix.org" # Let matrix.org handle sending emails for my users
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# msisdn: "http://localhost:8090" # Delegate contacting SMS numbers to this process
#
#account_threepid_delegate: ""
# Servers handling the above requests must answer the .../requestToken endpoints
# defined by the Matrix Identity Service API specification:
# https://matrix.org/docs/spec/identity_service/latest
#account_threepid_delegates:
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# email: ""
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
# msisdn: ""

# Users who register on this homeserver will automatically be joined
# to these rooms
Expand Down
4 changes: 2 additions & 2 deletions synapse/handlers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,10 @@ def _check_threepid(self, medium, authdict, password_servlet=False, **kwargs):
logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
if (
not password_servlet
or self.hs.config.threepid_behaviour == ThreepidBehaviour.REMOTE
or self.hs.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE
):
threepid = yield identity_handler.threepid_from_creds(threepid_creds)
elif self.hs.config.threepid_behaviour == ThreepidBehaviour.LOCAL:
elif self.hs.config.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
row = yield self.store.get_threepid_validation_session(
medium,
threepid_creds["client_secret"],
Expand Down
54 changes: 25 additions & 29 deletions synapse/rest/client/v2_alpha/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, hs):
self.config = hs.config
self.identity_handler = hs.get_handlers().identity_handler

if self.config.threepid_behaviour == ThreepidBehaviour.LOCAL:
if self.config.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
from synapse.push.mailer import Mailer, load_jinja2_templates

templates = load_jinja2_templates(
Expand All @@ -67,7 +67,7 @@ def __init__(self, hs):

@defer.inlineCallbacks
def on_POST(self, request):
if self.config.threepid_behaviour == ThreepidBehaviour.OFF:
if self.config.threepid_behaviour_email == ThreepidBehaviour.OFF:
if self.config.local_threepid_handling_disabled_due_to_email_config:
logger.warn(
"User password resets have been disabled due to lack of email config"
Expand Down Expand Up @@ -100,19 +100,19 @@ def on_POST(self, request):
if existing_user_id is None:
raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND)

if self.config.threepid_behaviour == ThreepidBehaviour.REMOTE:
if self.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
# Have the configured identity server handle the request
if not self.hs.config.account_threepid_delegate:
if not self.hs.config.account_threepid_delegate_email:
logger.warn(
"No upstream account_threepid_delegate configured on the server to handle "
"this request"
"No upstream email account_threepid_delegate configured on the server to "
"handle this request"
)
raise SynapseError(
400, "Password reset by email is not supported on this homeserver"
)

ret = yield self.identity_handler.requestEmailToken(
self.hs.config.account_threepid_delegate,
self.hs.config.account_threepid_delegate_email,
email,
client_secret,
send_attempt,
Expand Down Expand Up @@ -172,31 +172,27 @@ def on_POST(self, request):
if existing_user_id is None:
raise SynapseError(400, "MSISDN not found", Codes.THREEPID_NOT_FOUND)

if self.config.threepid_behaviour == ThreepidBehaviour.REMOTE:
if not self.hs.config.account_threepid_delegate:
logger.warn(
"No upstream account_threepid_delegate configured on the server to handle "
"this request"
)
raise SynapseError(
400,
"Password reset by phone number is not supported on this homeserver",
)

ret = yield self.identity_handler.requestMsisdnToken(
self.config.account_threepid_delegate,
country,
phone_number,
client_secret,
send_attempt,
next_link,
if not self.hs.config.account_threepid_delegate_msisdn:
logger.warn(
"No upstream msisdn account_threepid_delegate configured on the server to "
"handle this request"
)
raise SynapseError(
400,
"Password reset by phone number is not supported on this homeserver",
)
return (200, ret)

raise SynapseError(
400, "Password reset by phone number is not supported on this homeserver"
ret = yield self.identity_handler.requestMsisdnToken(
self.config.account_threepid_delegate_msisdn,
country,
phone_number,
client_secret,
send_attempt,
next_link,
)

return 200, ret


class PasswordResetSubmitTokenServlet(RestServlet):
"""Handles 3PID validation token submission"""
Expand All @@ -223,7 +219,7 @@ def on_GET(self, request, medium):
raise SynapseError(
400, "This medium is currently not supported for password resets"
)
if self.config.threepid_behaviour == ThreepidBehaviour.OFF:
if self.config.threepid_behaviour_email == ThreepidBehaviour.OFF:
if self.config.local_threepid_handling_disabled_due_to_email_config:
logger.warn(
"Password reset emails have been disabled due to lack of an email config"
Expand Down
Loading