diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index 61e569d412..7a059c6dec 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -1,4 +1,5 @@
# Copyright 2015, 2016 OpenMarket Ltd
+# Copyright 2021 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,6 +12,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+import argparse
+from typing import Optional
from synapse.api.constants import RoomCreationPreset
from synapse.config._base import Config, ConfigError
@@ -113,32 +116,73 @@ class RegistrationConfig(Config):
self.session_lifetime = session_lifetime
# The `refreshable_access_token_lifetime` applies for tokens that can be renewed
- # using a refresh token, as per MSC2918. If it is `None`, the refresh
- # token mechanism is disabled.
- #
- # Since it is incompatible with the `session_lifetime` mechanism, it is set to
- # `None` by default if a `session_lifetime` is set.
+ # using a refresh token, as per MSC2918.
+ # If it is `None`, the refresh token mechanism is disabled.
refreshable_access_token_lifetime = config.get(
"refreshable_access_token_lifetime",
- "5m" if session_lifetime is None else None,
+ "5m",
)
if refreshable_access_token_lifetime is not None:
refreshable_access_token_lifetime = self.parse_duration(
refreshable_access_token_lifetime
)
- self.refreshable_access_token_lifetime = refreshable_access_token_lifetime
+ self.refreshable_access_token_lifetime: Optional[
+ int
+ ] = refreshable_access_token_lifetime
if (
- session_lifetime is not None
- and refreshable_access_token_lifetime is not None
+ self.session_lifetime is not None
+ and "refreshable_access_token_lifetime" in config
):
- raise ConfigError(
- "The refresh token mechanism is incompatible with the "
- "`session_lifetime` option. Consider disabling the "
- "`session_lifetime` option or disabling the refresh token "
- "mechanism by removing the `refreshable_access_token_lifetime` "
- "option."
+ if self.session_lifetime < self.refreshable_access_token_lifetime:
+ raise ConfigError(
+ "Both `session_lifetime` and `refreshable_access_token_lifetime` "
+ "configuration options have been set, but `refreshable_access_token_lifetime` "
+ " exceeds `session_lifetime`!"
+ )
+
+ # The `nonrefreshable_access_token_lifetime` applies for tokens that can NOT be
+ # refreshed using a refresh token.
+ # If it is None, then these tokens last for the entire length of the session,
+ # which is infinite by default.
+ # The intention behind this configuration option is to help with requiring
+ # all clients to use refresh tokens, if the homeserver administrator requires.
+ nonrefreshable_access_token_lifetime = config.get(
+ "nonrefreshable_access_token_lifetime",
+ None,
+ )
+ if nonrefreshable_access_token_lifetime is not None:
+ nonrefreshable_access_token_lifetime = self.parse_duration(
+ nonrefreshable_access_token_lifetime
)
+ self.nonrefreshable_access_token_lifetime = nonrefreshable_access_token_lifetime
+
+ if (
+ self.session_lifetime is not None
+ and self.nonrefreshable_access_token_lifetime is not None
+ ):
+ if self.session_lifetime < self.nonrefreshable_access_token_lifetime:
+ raise ConfigError(
+ "Both `session_lifetime` and `nonrefreshable_access_token_lifetime` "
+ "configuration options have been set, but `nonrefreshable_access_token_lifetime` "
+ " exceeds `session_lifetime`!"
+ )
+
+ refresh_token_lifetime = config.get("refresh_token_lifetime")
+ if refresh_token_lifetime is not None:
+ refresh_token_lifetime = self.parse_duration(refresh_token_lifetime)
+ self.refresh_token_lifetime: Optional[int] = refresh_token_lifetime
+
+ if (
+ self.session_lifetime is not None
+ and self.refresh_token_lifetime is not None
+ ):
+ if self.session_lifetime < self.refresh_token_lifetime:
+ raise ConfigError(
+ "Both `session_lifetime` and `refresh_token_lifetime` "
+ "configuration options have been set, but `refresh_token_lifetime` "
+ " exceeds `session_lifetime`!"
+ )
# The fallback template used for authenticating using a registration token
self.registration_token_template = self.read_template("registration_token.html")
@@ -176,6 +220,44 @@ class RegistrationConfig(Config):
#
#session_lifetime: 24h
+ # Time that an access token remains valid for, if the session is
+ # using refresh tokens.
+ # For more information about refresh tokens, please see the manual.
+ # Note that this only applies to clients which advertise support for
+ # refresh tokens.
+ #
+ # Note also that this is calculated at login time and refresh time:
+ # changes are not applied to existing sessions until they are refreshed.
+ #
+ # By default, this is 5 minutes.
+ #
+ #refreshable_access_token_lifetime: 5m
+
+ # Time that a refresh token remains valid for (provided that it is not
+ # exchanged for another one first).
+ # This option can be used to automatically log-out inactive sessions.
+ # Please see the manual for more information.
+ #
+ # Note also that this is calculated at login time and refresh time:
+ # changes are not applied to existing sessions until they are refreshed.
+ #
+ # By default, this is infinite.
+ #
+ #refresh_token_lifetime: 24h
+
+ # Time that an access token remains valid for, if the session is NOT
+ # using refresh tokens.
+ # Please note that not all clients support refresh tokens, so setting
+ # this to a short value may be inconvenient for some users who will
+ # then be logged out frequently.
+ #
+ # Note also that this is calculated at login time: changes are not applied
+ # retrospectively to existing sessions for users that have already logged in.
+ #
+ # By default, this is infinite.
+ #
+ #nonrefreshable_access_token_lifetime: 24h
+
# The user must provide all of the below types of 3PID when registering.
#
#registrations_require_3pid:
@@ -369,7 +451,7 @@ class RegistrationConfig(Config):
)
@staticmethod
- def add_arguments(parser):
+ def add_arguments(parser: argparse.ArgumentParser) -> None:
reg_group = parser.add_argument_group("registration")
reg_group.add_argument(
"--enable-registration",
@@ -378,6 +460,6 @@ class RegistrationConfig(Config):
help="Enable registration for new users.",
)
- def read_arguments(self, args):
+ def read_arguments(self, args: argparse.Namespace) -> None:
if args.enable_registration is not None:
self.enable_registration = strtobool(str(args.enable_registration))
|