diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index a888d976f2..df1d83dfaa 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -13,10 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
-from typing import Any, Optional
+from typing import Any, Dict, Optional
from synapse.api.constants import RoomCreationPreset
-from synapse.config._base import Config, ConfigError
+from synapse.config._base import Config, ConfigError, read_file
from synapse.types import JsonDict, RoomAlias, UserID
from synapse.util.stringutils import random_string_with_symbols, strtobool
@@ -27,6 +27,11 @@ password resets, configure Synapse with an SMTP server via the `email` setting,
remove `account_threepid_delegates.email`.
"""
+CONFLICTING_SHARED_SECRET_OPTS_ERROR = """\
+You have configured both `registration_shared_secret` and
+`registration_shared_secret_path`. These are mutually incompatible.
+"""
+
class RegistrationConfig(Config):
section = "registration"
@@ -53,7 +58,16 @@ class RegistrationConfig(Config):
self.enable_registration_token_3pid_bypass = config.get(
"enable_registration_token_3pid_bypass", False
)
+
+ # read the shared secret, either inline or from an external file
self.registration_shared_secret = config.get("registration_shared_secret")
+ registration_shared_secret_path = config.get("registration_shared_secret_path")
+ if registration_shared_secret_path:
+ if self.registration_shared_secret:
+ raise ConfigError(CONFLICTING_SHARED_SECRET_OPTS_ERROR)
+ self.registration_shared_secret = read_file(
+ registration_shared_secret_path, ("registration_shared_secret_path",)
+ ).strip()
self.bcrypt_rounds = config.get("bcrypt_rounds", 12)
@@ -218,6 +232,21 @@ class RegistrationConfig(Config):
else:
return ""
+ def generate_files(self, config: Dict[str, Any], config_dir_path: str) -> None:
+ # if 'registration_shared_secret_path' is specified, and the target file
+ # does not exist, generate it.
+ registration_shared_secret_path = config.get("registration_shared_secret_path")
+ if registration_shared_secret_path and not self.path_exists(
+ registration_shared_secret_path
+ ):
+ print(
+ "Generating registration shared secret file "
+ + registration_shared_secret_path
+ )
+ secret = random_string_with_symbols(50)
+ with open(registration_shared_secret_path, "w") as f:
+ f.write(f"{secret}\n")
+
@staticmethod
def add_arguments(parser: argparse.ArgumentParser) -> None:
reg_group = parser.add_argument_group("registration")
|