registration.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2015, 2016 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import os
  16. import pkg_resources
  17. from synapse.api.constants import RoomCreationPreset
  18. from synapse.config._base import Config, ConfigError
  19. from synapse.types import RoomAlias, UserID
  20. from synapse.util.stringutils import random_string_with_symbols, strtobool
  21. class AccountValidityConfig(Config):
  22. section = "accountvalidity"
  23. def __init__(self, config, synapse_config):
  24. if config is None:
  25. return
  26. super().__init__()
  27. self.enabled = config.get("enabled", False)
  28. self.renew_by_email_enabled = "renew_at" in config
  29. if self.enabled:
  30. if "period" in config:
  31. self.period = self.parse_duration(config["period"])
  32. else:
  33. raise ConfigError("'period' is required when using account validity")
  34. if "renew_at" in config:
  35. self.renew_at = self.parse_duration(config["renew_at"])
  36. if "renew_email_subject" in config:
  37. self.renew_email_subject = config["renew_email_subject"]
  38. else:
  39. self.renew_email_subject = "Renew your %(app)s account"
  40. self.startup_job_max_delta = self.period * 10.0 / 100.0
  41. if self.renew_by_email_enabled:
  42. if "public_baseurl" not in synapse_config:
  43. raise ConfigError("Can't send renewal emails without 'public_baseurl'")
  44. template_dir = config.get("template_dir")
  45. if not template_dir:
  46. template_dir = pkg_resources.resource_filename("synapse", "res/templates")
  47. if "account_renewed_html_path" in config:
  48. file_path = os.path.join(template_dir, config["account_renewed_html_path"])
  49. self.account_renewed_html_content = self.read_file(
  50. file_path, "account_validity.account_renewed_html_path"
  51. )
  52. else:
  53. self.account_renewed_html_content = (
  54. "<html><body>Your account has been successfully renewed.</body><html>"
  55. )
  56. if "invalid_token_html_path" in config:
  57. file_path = os.path.join(template_dir, config["invalid_token_html_path"])
  58. self.invalid_token_html_content = self.read_file(
  59. file_path, "account_validity.invalid_token_html_path"
  60. )
  61. else:
  62. self.invalid_token_html_content = (
  63. "<html><body>Invalid renewal token.</body><html>"
  64. )
  65. class RegistrationConfig(Config):
  66. section = "registration"
  67. def read_config(self, config, **kwargs):
  68. self.enable_registration = strtobool(
  69. str(config.get("enable_registration", False))
  70. )
  71. if "disable_registration" in config:
  72. self.enable_registration = not strtobool(
  73. str(config["disable_registration"])
  74. )
  75. self.account_validity = AccountValidityConfig(
  76. config.get("account_validity") or {}, config
  77. )
  78. self.registrations_require_3pid = config.get("registrations_require_3pid", [])
  79. self.allowed_local_3pids = config.get("allowed_local_3pids", [])
  80. self.enable_3pid_lookup = config.get("enable_3pid_lookup", True)
  81. self.registration_shared_secret = config.get("registration_shared_secret")
  82. self.bcrypt_rounds = config.get("bcrypt_rounds", 12)
  83. self.trusted_third_party_id_servers = config.get(
  84. "trusted_third_party_id_servers", ["matrix.org", "vector.im"]
  85. )
  86. account_threepid_delegates = config.get("account_threepid_delegates") or {}
  87. self.account_threepid_delegate_email = account_threepid_delegates.get("email")
  88. self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
  89. if self.account_threepid_delegate_msisdn and not self.public_baseurl:
  90. raise ConfigError(
  91. "The configuration option `public_baseurl` is required if "
  92. "`account_threepid_delegate.msisdn` is set, such that "
  93. "clients know where to submit validation tokens to. Please "
  94. "configure `public_baseurl`."
  95. )
  96. self.default_identity_server = config.get("default_identity_server")
  97. self.allow_guest_access = config.get("allow_guest_access", False)
  98. if config.get("invite_3pid_guest", False):
  99. raise ConfigError("invite_3pid_guest is no longer supported")
  100. self.auto_join_rooms = config.get("auto_join_rooms", [])
  101. for room_alias in self.auto_join_rooms:
  102. if not RoomAlias.is_valid(room_alias):
  103. raise ConfigError("Invalid auto_join_rooms entry %s" % (room_alias,))
  104. # Options for creating auto-join rooms if they do not exist yet.
  105. self.autocreate_auto_join_rooms = config.get("autocreate_auto_join_rooms", True)
  106. self.autocreate_auto_join_rooms_federated = config.get(
  107. "autocreate_auto_join_rooms_federated", True
  108. )
  109. self.autocreate_auto_join_room_preset = (
  110. config.get("autocreate_auto_join_room_preset")
  111. or RoomCreationPreset.PUBLIC_CHAT
  112. )
  113. self.auto_join_room_requires_invite = self.autocreate_auto_join_room_preset in {
  114. RoomCreationPreset.PRIVATE_CHAT,
  115. RoomCreationPreset.TRUSTED_PRIVATE_CHAT,
  116. }
  117. # Pull the creator/inviter from the configuration, this gets used to
  118. # send invites for invite-only rooms.
  119. mxid_localpart = config.get("auto_join_mxid_localpart")
  120. self.auto_join_user_id = None
  121. if mxid_localpart:
  122. # Convert the localpart to a full mxid.
  123. self.auto_join_user_id = UserID(
  124. mxid_localpart, self.server_name
  125. ).to_string()
  126. if self.autocreate_auto_join_rooms:
  127. # Ensure the preset is a known value.
  128. if self.autocreate_auto_join_room_preset not in {
  129. RoomCreationPreset.PUBLIC_CHAT,
  130. RoomCreationPreset.PRIVATE_CHAT,
  131. RoomCreationPreset.TRUSTED_PRIVATE_CHAT,
  132. }:
  133. raise ConfigError("Invalid value for autocreate_auto_join_room_preset")
  134. # If the preset requires invitations to be sent, ensure there's a
  135. # configured user to send them from.
  136. if self.auto_join_room_requires_invite:
  137. if not mxid_localpart:
  138. raise ConfigError(
  139. "The configuration option `auto_join_mxid_localpart` is required if "
  140. "`autocreate_auto_join_room_preset` is set to private_chat or trusted_private_chat, such that "
  141. "Synapse knows who to send invitations from. Please "
  142. "configure `auto_join_mxid_localpart`."
  143. )
  144. self.auto_join_rooms_for_guests = config.get("auto_join_rooms_for_guests", True)
  145. self.enable_set_displayname = config.get("enable_set_displayname", True)
  146. self.enable_set_avatar_url = config.get("enable_set_avatar_url", True)
  147. self.enable_3pid_changes = config.get("enable_3pid_changes", True)
  148. self.disable_msisdn_registration = config.get(
  149. "disable_msisdn_registration", False
  150. )
  151. session_lifetime = config.get("session_lifetime")
  152. if session_lifetime is not None:
  153. session_lifetime = self.parse_duration(session_lifetime)
  154. self.session_lifetime = session_lifetime
  155. # The success template used during fallback auth.
  156. self.fallback_success_template = self.read_template("auth_success.html")
  157. def generate_config_section(self, generate_secrets=False, **kwargs):
  158. if generate_secrets:
  159. registration_shared_secret = 'registration_shared_secret: "%s"' % (
  160. random_string_with_symbols(50),
  161. )
  162. else:
  163. registration_shared_secret = "#registration_shared_secret: <PRIVATE STRING>"
  164. return (
  165. """\
  166. ## Registration ##
  167. #
  168. # Registration can be rate-limited using the parameters in the "Ratelimiting"
  169. # section of this file.
  170. # Enable registration for new users.
  171. #
  172. #enable_registration: false
  173. # Optional account validity configuration. This allows for accounts to be denied
  174. # any request after a given period.
  175. #
  176. # Once this feature is enabled, Synapse will look for registered users without an
  177. # expiration date at startup and will add one to every account it found using the
  178. # current settings at that time.
  179. # This means that, if a validity period is set, and Synapse is restarted (it will
  180. # then derive an expiration date from the current validity period), and some time
  181. # after that the validity period changes and Synapse is restarted, the users'
  182. # expiration dates won't be updated unless their account is manually renewed. This
  183. # date will be randomly selected within a range [now + period - d ; now + period],
  184. # where d is equal to 10%% of the validity period.
  185. #
  186. account_validity:
  187. # The account validity feature is disabled by default. Uncomment the
  188. # following line to enable it.
  189. #
  190. #enabled: true
  191. # The period after which an account is valid after its registration. When
  192. # renewing the account, its validity period will be extended by this amount
  193. # of time. This parameter is required when using the account validity
  194. # feature.
  195. #
  196. #period: 6w
  197. # The amount of time before an account's expiry date at which Synapse will
  198. # send an email to the account's email address with a renewal link. By
  199. # default, no such emails are sent.
  200. #
  201. # If you enable this setting, you will also need to fill out the 'email' and
  202. # 'public_baseurl' configuration sections.
  203. #
  204. #renew_at: 1w
  205. # The subject of the email sent out with the renewal link. '%%(app)s' can be
  206. # used as a placeholder for the 'app_name' parameter from the 'email'
  207. # section.
  208. #
  209. # Note that the placeholder must be written '%%(app)s', including the
  210. # trailing 's'.
  211. #
  212. # If this is not set, a default value is used.
  213. #
  214. #renew_email_subject: "Renew your %%(app)s account"
  215. # Directory in which Synapse will try to find templates for the HTML files to
  216. # serve to the user when trying to renew an account. If not set, default
  217. # templates from within the Synapse package will be used.
  218. #
  219. #template_dir: "res/templates"
  220. # File within 'template_dir' giving the HTML to be displayed to the user after
  221. # they successfully renewed their account. If not set, default text is used.
  222. #
  223. #account_renewed_html_path: "account_renewed.html"
  224. # File within 'template_dir' giving the HTML to be displayed when the user
  225. # tries to renew an account with an invalid renewal token. If not set,
  226. # default text is used.
  227. #
  228. #invalid_token_html_path: "invalid_token.html"
  229. # Time that a user's session remains valid for, after they log in.
  230. #
  231. # Note that this is not currently compatible with guest logins.
  232. #
  233. # Note also that this is calculated at login time: changes are not applied
  234. # retrospectively to users who have already logged in.
  235. #
  236. # By default, this is infinite.
  237. #
  238. #session_lifetime: 24h
  239. # The user must provide all of the below types of 3PID when registering.
  240. #
  241. #registrations_require_3pid:
  242. # - email
  243. # - msisdn
  244. # Explicitly disable asking for MSISDNs from the registration
  245. # flow (overrides registrations_require_3pid if MSISDNs are set as required)
  246. #
  247. #disable_msisdn_registration: true
  248. # Mandate that users are only allowed to associate certain formats of
  249. # 3PIDs with accounts on this server.
  250. #
  251. #allowed_local_3pids:
  252. # - medium: email
  253. # pattern: '.*@matrix\\.org'
  254. # - medium: email
  255. # pattern: '.*@vector\\.im'
  256. # - medium: msisdn
  257. # pattern: '\\+44'
  258. # Enable 3PIDs lookup requests to identity servers from this server.
  259. #
  260. #enable_3pid_lookup: true
  261. # If set, allows registration of standard or admin accounts by anyone who
  262. # has the shared secret, even if registration is otherwise disabled.
  263. #
  264. %(registration_shared_secret)s
  265. # Set the number of bcrypt rounds used to generate password hash.
  266. # Larger numbers increase the work factor needed to generate the hash.
  267. # The default number is 12 (which equates to 2^12 rounds).
  268. # N.B. that increasing this will exponentially increase the time required
  269. # to register or login - e.g. 24 => 2^24 rounds which will take >20 mins.
  270. #
  271. #bcrypt_rounds: 12
  272. # Allows users to register as guests without a password/email/etc, and
  273. # participate in rooms hosted on this server which have been made
  274. # accessible to anonymous users.
  275. #
  276. #allow_guest_access: false
  277. # The identity server which we suggest that clients should use when users log
  278. # in on this server.
  279. #
  280. # (By default, no suggestion is made, so it is left up to the client.
  281. # This setting is ignored unless public_baseurl is also set.)
  282. #
  283. #default_identity_server: https://matrix.org
  284. # Handle threepid (email/phone etc) registration and password resets through a set of
  285. # *trusted* identity servers. Note that this allows the configured identity server to
  286. # reset passwords for accounts!
  287. #
  288. # Be aware that if `email` is not set, and SMTP options have not been
  289. # configured in the email config block, registration and user password resets via
  290. # email will be globally disabled.
  291. #
  292. # Additionally, if `msisdn` is not set, registration and password resets via msisdn
  293. # will be disabled regardless, and users will not be able to associate an msisdn
  294. # identifier to their account. This is due to Synapse currently not supporting
  295. # any method of sending SMS messages on its own.
  296. #
  297. # To enable using an identity server for operations regarding a particular third-party
  298. # identifier type, set the value to the URL of that identity server as shown in the
  299. # examples below.
  300. #
  301. # Servers handling the these requests must answer the `/requestToken` endpoints defined
  302. # by the Matrix Identity Service API specification:
  303. # https://matrix.org/docs/spec/identity_service/latest
  304. #
  305. # If a delegate is specified, the config option public_baseurl must also be filled out.
  306. #
  307. account_threepid_delegates:
  308. #email: https://example.com # Delegate email sending to example.com
  309. #msisdn: http://localhost:8090 # Delegate SMS sending to this local process
  310. # Whether users are allowed to change their displayname after it has
  311. # been initially set. Useful when provisioning users based on the
  312. # contents of a third-party directory.
  313. #
  314. # Does not apply to server administrators. Defaults to 'true'
  315. #
  316. #enable_set_displayname: false
  317. # Whether users are allowed to change their avatar after it has been
  318. # initially set. Useful when provisioning users based on the contents
  319. # of a third-party directory.
  320. #
  321. # Does not apply to server administrators. Defaults to 'true'
  322. #
  323. #enable_set_avatar_url: false
  324. # Whether users can change the 3PIDs associated with their accounts
  325. # (email address and msisdn).
  326. #
  327. # Defaults to 'true'
  328. #
  329. #enable_3pid_changes: false
  330. # Users who register on this homeserver will automatically be joined
  331. # to these rooms.
  332. #
  333. # By default, any room aliases included in this list will be created
  334. # as a publicly joinable room when the first user registers for the
  335. # homeserver. This behaviour can be customised with the settings below.
  336. # If the room already exists, make certain it is a publicly joinable
  337. # room. The join rule of the room must be set to 'public'.
  338. #
  339. #auto_join_rooms:
  340. # - "#example:example.com"
  341. # Where auto_join_rooms are specified, setting this flag ensures that the
  342. # the rooms exist by creating them when the first user on the
  343. # homeserver registers.
  344. #
  345. # By default the auto-created rooms are publicly joinable from any federated
  346. # server. Use the autocreate_auto_join_rooms_federated and
  347. # autocreate_auto_join_room_preset settings below to customise this behaviour.
  348. #
  349. # Setting to false means that if the rooms are not manually created,
  350. # users cannot be auto-joined since they do not exist.
  351. #
  352. # Defaults to true. Uncomment the following line to disable automatically
  353. # creating auto-join rooms.
  354. #
  355. #autocreate_auto_join_rooms: false
  356. # Whether the auto_join_rooms that are auto-created are available via
  357. # federation. Only has an effect if autocreate_auto_join_rooms is true.
  358. #
  359. # Note that whether a room is federated cannot be modified after
  360. # creation.
  361. #
  362. # Defaults to true: the room will be joinable from other servers.
  363. # Uncomment the following to prevent users from other homeservers from
  364. # joining these rooms.
  365. #
  366. #autocreate_auto_join_rooms_federated: false
  367. # The room preset to use when auto-creating one of auto_join_rooms. Only has an
  368. # effect if autocreate_auto_join_rooms is true.
  369. #
  370. # This can be one of "public_chat", "private_chat", or "trusted_private_chat".
  371. # If a value of "private_chat" or "trusted_private_chat" is used then
  372. # auto_join_mxid_localpart must also be configured.
  373. #
  374. # Defaults to "public_chat", meaning that the room is joinable by anyone, including
  375. # federated servers if autocreate_auto_join_rooms_federated is true (the default).
  376. # Uncomment the following to require an invitation to join these rooms.
  377. #
  378. #autocreate_auto_join_room_preset: private_chat
  379. # The local part of the user id which is used to create auto_join_rooms if
  380. # autocreate_auto_join_rooms is true. If this is not provided then the
  381. # initial user account that registers will be used to create the rooms.
  382. #
  383. # The user id is also used to invite new users to any auto-join rooms which
  384. # are set to invite-only.
  385. #
  386. # It *must* be configured if autocreate_auto_join_room_preset is set to
  387. # "private_chat" or "trusted_private_chat".
  388. #
  389. # Note that this must be specified in order for new users to be correctly
  390. # invited to any auto-join rooms which have been set to invite-only (either
  391. # at the time of creation or subsequently).
  392. #
  393. # Note that, if the room already exists, this user must be joined and
  394. # have the appropriate permissions to invite new members.
  395. #
  396. #auto_join_mxid_localpart: system
  397. # When auto_join_rooms is specified, setting this flag to false prevents
  398. # guest accounts from being automatically joined to the rooms.
  399. #
  400. # Defaults to true.
  401. #
  402. #auto_join_rooms_for_guests: false
  403. """
  404. % locals()
  405. )
  406. @staticmethod
  407. def add_arguments(parser):
  408. reg_group = parser.add_argument_group("registration")
  409. reg_group.add_argument(
  410. "--enable-registration",
  411. action="store_true",
  412. default=None,
  413. help="Enable registration for new users.",
  414. )
  415. def read_arguments(self, args):
  416. if args.enable_registration is not None:
  417. self.enable_registration = bool(strtobool(str(args.enable_registration)))