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

Replace trust_identity_server_for_password_resets with account_threepid_delegate #5876

Merged
merged 23 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions changelog.d/5876.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace `trust_identity_server_for_password_resets` config option with `account_threepid_delegate`.
26 changes: 13 additions & 13 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,19 @@ 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")
#
#account_threepid_delegate: ""

# Users who register on this homeserver will automatically be joined
# to these rooms
#
Expand Down Expand Up @@ -1163,19 +1176,6 @@ password_config:
# #
# riot_base_url: "http://localhost/riot"
#
# # Enable sending password reset emails via the configured, trusted
# # identity servers
# #
# # IMPORTANT! This will give a malicious or overtaken identity server
# # the ability to reset passwords for your users! Make absolutely sure
# # that you want to do this! It is strongly recommended that password
# # reset emails be sent by the homeserver instead
# #
# # If this option is set to false and SMTP options have not been
# # configured, resetting user passwords via email will be disabled
# #
# #trust_identity_server_for_password_resets: false
#
# # Configure the time that a validation email or text message code
# # will expire after sending
# #
Expand Down
53 changes: 29 additions & 24 deletions synapse/config/emailconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,37 @@ def read_config(self, config, **kwargs):
"renew_at"
)

email_trust_identity_server_for_password_resets = email_config.get(
"trust_identity_server_for_password_resets", False
self.email_threepid_behaviour = (
# Have Synapse handle the email sending if account_threepid_delegate
# is not defined
"remote"
if self.account_threepid_delegate
else "local"
)
self.email_password_reset_behaviour = (
"remote" if email_trust_identity_server_for_password_resets else "local"
)
self.password_resets_were_disabled_due_to_email_config = False
if self.email_password_reset_behaviour == "local" and email_config == {}:
# Prior to Synapse v1.4.0, there was another option that defined whether Synapse would
# use an identity server to password reset tokens on its behalf. We now warn the user
# if they have this set and tell them to use the updated option, while using a default
# identity server in the process.
if config.get("trust_identity_server_for_password_resets", False) is True:
# Use the first entry in self.trusted_third_party_id_servers instead
if len(self.trusted_third_party_id_servers):
self.account_threepid_delegate = self.trusted_third_party_id_servers[0]
else:
raise ConfigError(
'The config option "trust_identity_server_for_password_resets" '
'has been replaced by "account_threepid_delegate". Attempted to use an '
'identity server from "trusted_third_party_id_servers" but it is empty. '
"Please consult the sample config at docs/sample_config.yaml for "
"details and update your config file."
)

self.local_threepid_emails_disabled_due_to_config = False
if self.email_threepid_behaviour == "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.password_resets_were_disabled_due_to_email_config = True
self.local_threepid_emails_disabled_due_to_config = True

self.email_password_reset_behaviour = "off"
self.email_threepid_behaviour = "off"

# Get lifetime of a validation token in milliseconds
self.email_validation_token_lifetime = self.parse_duration(
Expand All @@ -96,7 +114,7 @@ def read_config(self, config, **kwargs):
if (
self.email_enable_notifs
or account_validity_renewal_enabled
or self.email_password_reset_behaviour == "local"
or self.email_threepid_behaviour == "local"
):
# make sure we can import the required deps
import jinja2
Expand All @@ -106,7 +124,7 @@ def read_config(self, config, **kwargs):
jinja2
bleach

if self.email_password_reset_behaviour == "local":
if self.email_threepid_behaviour == "local":
required = ["smtp_host", "smtp_port", "notif_from"]

missing = []
Expand Down Expand Up @@ -239,19 +257,6 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
# #
# riot_base_url: "http://localhost/riot"
#
# # Enable sending password reset emails via the configured, trusted
# # identity servers
# #
# # IMPORTANT! This will give a malicious or overtaken identity server
# # the ability to reset passwords for your users! Make absolutely sure
# # that you want to do this! It is strongly recommended that password
# # reset emails be sent by the homeserver instead
# #
# # If this option is set to false and SMTP options have not been
# # configured, resetting user passwords via email will be disabled
# #
# #trust_identity_server_for_password_resets: false
#
# # Configure the time that a validation email or text message code
# # will expire after sending
# #
Expand Down
14 changes: 14 additions & 0 deletions synapse/config/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ 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")
self.default_identity_server = config.get("default_identity_server")
self.allow_guest_access = config.get("allow_guest_access", False)

Expand Down Expand Up @@ -269,6 +270,19 @@ 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.
#
# 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")
#
#account_threepid_delegate: ""

# Users who register on this homeserver will automatically be joined
# to these rooms
#
Expand Down
7 changes: 2 additions & 5 deletions synapse/handlers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,12 +458,9 @@ def _check_threepid(self, medium, authdict, password_servlet=False, **kwargs):
identity_handler = self.hs.get_handlers().identity_handler

logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
if (
not password_servlet
or self.hs.config.email_password_reset_behaviour == "remote"
):
if not password_servlet or self.hs.config.email_threepid_behaviour == "remote":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is doing this for non password reset still the correct thing to do?

Copy link
Member Author

@anoadragon453 anoadragon453 Aug 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be removed in part 2 of #5835

threepid = yield identity_handler.threepid_from_creds(threepid_creds)
elif self.hs.config.email_password_reset_behaviour == "local":
elif self.hs.config.email_threepid_behaviour == "local":
row = yield self.store.get_threepid_validation_session(
medium,
threepid_creds["client_secret"],
Expand Down
38 changes: 32 additions & 6 deletions synapse/handlers/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,22 @@ def try_unbind_threepid_with_id_server(self, mxid, threepid, id_server):

@defer.inlineCallbacks
def requestEmailToken(
self, id_server, email, client_secret, send_attempt, next_link=None
self, email, client_secret, send_attempt, next_link=None, **kwargs
):
"""
Request an external server send an email on our behalf for the purposes of threepid
validation.

Args:
email (str): The email to send the message to
client_secret (str): The unique client_secret sends by the user
send_attempt (int): Which attempt this is
next_link: A link to redirect the user to once they submit the token
kwargs: extra arguments to send to the server

Returns:
The json response body from the server
"""
params = {
"email": email,
"client_secret": client_secret,
Expand All @@ -209,9 +223,9 @@ def requestEmailToken(
params.update({"next_link": next_link})

try:
id_server = self.hs.config.account_threepid_delegate
data = yield self.http_client.post_json_get_json(
"https://%s%s"
% (id_server, "/_matrix/identity/api/v1/validate/email/requestToken"),
id_server + "/_matrix/identity/api/v1/validate/email/requestToken",
params,
)
return data
Expand All @@ -221,8 +235,20 @@ def requestEmailToken(

@defer.inlineCallbacks
def requestMsisdnToken(
self, id_server, country, phone_number, client_secret, send_attempt, **kwargs
self, country, phone_number, client_secret, send_attempt, **kwargs
):
"""
Request an external server send an SMS message on our behalf for the purposes of
threepid validation.
Args:
country (str): The country code of the phone number
phone_number (str): The number to send the message to
client_secret (str): The unique client_secret sends by the user
send_attempt (int): Which attempt this is
kwargs: extra arguments to send to the server
Returns:
The json response body from the server
"""
params = {
"country": country,
"phone_number": phone_number,
Expand All @@ -232,9 +258,9 @@ def requestMsisdnToken(
params.update(kwargs)

try:
id_server = self.hs.config.account_threepid_delegate
data = yield self.http_client.post_json_get_json(
"https://%s%s"
% (id_server, "/_matrix/identity/api/v1/validate/msisdn/requestToken"),
id_server + "/_matrix/identity/api/v1/validate/msisdn/requestToken",
params,
)
return data
Expand Down
14 changes: 8 additions & 6 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.email_password_reset_behaviour == "local":
if self.config.email_threepid_behaviour == "local":
from synapse.push.mailer import Mailer, load_jinja2_templates

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

@defer.inlineCallbacks
def on_POST(self, request):
if self.config.email_password_reset_behaviour == "off":
if self.config.password_resets_were_disabled_due_to_email_config:
if self.config.email_threepid_behaviour == "off":
if self.config.local_threepid_emails_disabled_due_to_config:
logger.warn(
"User password resets have been disabled due to lack of email config"
)
Expand Down Expand Up @@ -100,7 +100,7 @@ def on_POST(self, request):
if existingUid is None:
raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND)

if self.config.email_password_reset_behaviour == "remote":
if self.config.email_threepid_behaviour == "remote":
if "id_server" not in body:
raise SynapseError(400, "Missing 'id_server' param in body")

Expand All @@ -127,6 +127,8 @@ def send_password_reset(self, email, client_secret, send_attempt, next_link=None
email (str): The user's email address
client_secret (str): The provided client secret
send_attempt (int): Which send attempt this is
next_link (str|None): The link to redirect the user to upon success. No redirect
occurs if None

Returns:
The new session_id upon success
Expand Down Expand Up @@ -249,8 +251,8 @@ def on_GET(self, request, medium):
raise SynapseError(
400, "This medium is currently not supported for password resets"
)
if self.config.email_password_reset_behaviour == "off":
if self.config.password_resets_were_disabled_due_to_email_config:
if self.config.email_threepid_behaviour == "off":
if self.config.local_threepid_emails_disabled_due_to_config:
logger.warn(
"User password resets have been disabled due to lack of email config"
)
Expand Down