summary refs log tree commit diff
path: root/synapse/config/registration.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/config/registration.py')
-rw-r--r--synapse/config/registration.py116
1 files changed, 99 insertions, 17 deletions
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))