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

Commit

Permalink
Merge pull request #5047 from matrix-org/babolivier/account_expiration
Browse files Browse the repository at this point in the history
Send out emails with links to extend an account's validity period
  • Loading branch information
babolivier authored Apr 17, 2019
2 parents 49ff74d + 20f0617 commit 9193402
Show file tree
Hide file tree
Showing 17 changed files with 699 additions and 43 deletions.
1 change: 1 addition & 0 deletions changelog.d/5047.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add time-based account expiration.
29 changes: 26 additions & 3 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,31 @@ uploads_path: "DATADIR/uploads"
#
#enable_registration: false

# Optional account validity parameter. This allows for, e.g., accounts to
# be denied any request after a given period.
# Optional account validity configuration. This allows for accounts to be denied
# any request after a given period.
#
# ``enabled`` defines whether the account validity feature is enabled. Defaults
# to False.
#
# ``period`` allows setting the period after which an account is valid
# after its registration. When renewing the account, its validity period
# will be extended by this amount of time. This parameter is required when using
# the account validity feature.
#
# ``renew_at`` is the amount of time before an account's expiry date at which
# Synapse will send an email to the account's email address with a renewal link.
# This needs the ``email`` and ``public_baseurl`` configuration sections to be
# filled.
#
# ``renew_email_subject`` is the subject of the email sent out with the renewal
# link. ``%(app)s`` can be used as a placeholder for the ``app_name`` parameter
# from the ``email`` section.
#
#account_validity:
# enabled: True
# period: 6w
# renew_at: 1w
# renew_email_subject: "Renew your %(app)s account"

# The user must provide all of the below types of 3PID when registering.
#
Expand Down Expand Up @@ -897,7 +917,7 @@ password_config:



# Enable sending emails for notification events
# Enable sending emails for notification events or expiry notices
# Defining a custom URL for Riot is only needed if email notifications
# should contain links to a self-hosted installation of Riot; when set
# the "app_name" setting is ignored.
Expand All @@ -919,6 +939,9 @@ password_config:
# #template_dir: res/templates
# notif_template_html: notif_mail.html
# notif_template_text: notif_mail.txt
# # Templates for account expiry notices.
# expiry_template_html: notice_expiry.html
# expiry_template_text: notice_expiry.txt
# notif_for_new_users: True
# riot_base_url: "http://localhost/riot"

Expand Down
5 changes: 3 additions & 2 deletions synapse/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ def get_user_by_req(self, request, allow_guest=False, rights="access"):

# Deny the request if the user account has expired.
if self._account_validity.enabled:
expiration_ts = yield self.store.get_expiration_ts_for_user(user)
if self.clock.time_msec() >= expiration_ts:
user_id = user.to_string()
expiration_ts = yield self.store.get_expiration_ts_for_user(user_id)
if expiration_ts and self.clock.time_msec() >= expiration_ts:
raise AuthError(
403,
"User account has expired",
Expand Down
7 changes: 6 additions & 1 deletion synapse/config/emailconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def read_config(self, config):
self.email_notif_from = email_config["notif_from"]
self.email_notif_template_html = email_config["notif_template_html"]
self.email_notif_template_text = email_config["notif_template_text"]
self.email_expiry_template_html = email_config["expiry_template_html"]
self.email_expiry_template_text = email_config["expiry_template_text"]

template_dir = email_config.get("template_dir")
# we need an absolute path, because we change directory after starting (and
Expand Down Expand Up @@ -120,7 +122,7 @@ def read_config(self, config):

def default_config(self, config_dir_path, server_name, **kwargs):
return """
# Enable sending emails for notification events
# Enable sending emails for notification events or expiry notices
# Defining a custom URL for Riot is only needed if email notifications
# should contain links to a self-hosted installation of Riot; when set
# the "app_name" setting is ignored.
Expand All @@ -142,6 +144,9 @@ def default_config(self, config_dir_path, server_name, **kwargs):
# #template_dir: res/templates
# notif_template_html: notif_mail.html
# notif_template_text: notif_mail.txt
# # Templates for account expiry notices.
# expiry_template_html: notice_expiry.html
# expiry_template_text: notice_expiry.txt
# notif_for_new_users: True
# riot_base_url: "http://localhost/riot"
"""
52 changes: 44 additions & 8 deletions synapse/config/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,26 @@


class AccountValidityConfig(Config):
def __init__(self, config):
self.enabled = (len(config) > 0)
def __init__(self, config, synapse_config):
self.enabled = config.get("enabled", False)
self.renew_by_email_enabled = ("renew_at" in config)

period = config.get("period", None)
if period:
self.period = self.parse_duration(period)
if self.enabled:
if "period" in config:
self.period = self.parse_duration(config["period"])
else:
raise ConfigError("'period' is required when using account validity")

if "renew_at" in config:
self.renew_at = self.parse_duration(config["renew_at"])

if "renew_email_subject" in config:
self.renew_email_subject = config["renew_email_subject"]
else:
self.renew_email_subject = "Renew your %(app)s account"

if self.renew_by_email_enabled and "public_baseurl" not in synapse_config:
raise ConfigError("Can't send renewal emails without 'public_baseurl'")


class RegistrationConfig(Config):
Expand All @@ -40,7 +54,9 @@ def read_config(self, config):
strtobool(str(config["disable_registration"]))
)

self.account_validity = AccountValidityConfig(config.get("account_validity", {}))
self.account_validity = AccountValidityConfig(
config.get("account_validity", {}), config,
)

self.registrations_require_3pid = config.get("registrations_require_3pid", [])
self.allowed_local_3pids = config.get("allowed_local_3pids", [])
Expand Down Expand Up @@ -87,11 +103,31 @@ def default_config(self, generate_secrets=False, **kwargs):
#
#enable_registration: false
# Optional account validity parameter. This allows for, e.g., accounts to
# be denied any request after a given period.
# Optional account validity configuration. This allows for accounts to be denied
# any request after a given period.
#
# ``enabled`` defines whether the account validity feature is enabled. Defaults
# to False.
#
# ``period`` allows setting the period after which an account is valid
# after its registration. When renewing the account, its validity period
# will be extended by this amount of time. This parameter is required when using
# the account validity feature.
#
# ``renew_at`` is the amount of time before an account's expiry date at which
# Synapse will send an email to the account's email address with a renewal link.
# This needs the ``email`` and ``public_baseurl`` configuration sections to be
# filled.
#
# ``renew_email_subject`` is the subject of the email sent out with the renewal
# link. ``%%(app)s`` can be used as a placeholder for the ``app_name`` parameter
# from the ``email`` section.
#
#account_validity:
# enabled: True
# period: 6w
# renew_at: 1w
# renew_email_subject: "Renew your %%(app)s account"
# The user must provide all of the below types of 3PID when registering.
#
Expand Down
Loading

0 comments on commit 9193402

Please sign in to comment.