You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

482 lines
20 KiB

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