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.
 
 
 
 
 
 

277 lines
13 KiB

  1. # Copyright 2020 The Matrix.org Foundation C.I.C.
  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. from typing import Any, Dict, Optional
  15. import attr
  16. from ._base import Config
  17. @attr.s(frozen=True)
  18. class SsoAttributeRequirement:
  19. """Object describing a single requirement for SSO attributes."""
  20. attribute = attr.ib(type=str)
  21. # If a value is not given, than the attribute must simply exist.
  22. value = attr.ib(type=Optional[str])
  23. JSON_SCHEMA = {
  24. "type": "object",
  25. "properties": {"attribute": {"type": "string"}, "value": {"type": "string"}},
  26. "required": ["attribute", "value"],
  27. }
  28. class SSOConfig(Config):
  29. """SSO Configuration"""
  30. section = "sso"
  31. def read_config(self, config, **kwargs):
  32. sso_config = config.get("sso") or {} # type: Dict[str, Any]
  33. # The sso-specific template_dir
  34. self.sso_template_dir = sso_config.get("template_dir")
  35. # Read templates from disk
  36. (
  37. self.sso_login_idp_picker_template,
  38. self.sso_redirect_confirm_template,
  39. self.sso_auth_confirm_template,
  40. self.sso_error_template,
  41. sso_account_deactivated_template,
  42. sso_auth_success_template,
  43. self.sso_auth_bad_user_template,
  44. ) = self.read_templates(
  45. [
  46. "sso_login_idp_picker.html",
  47. "sso_redirect_confirm.html",
  48. "sso_auth_confirm.html",
  49. "sso_error.html",
  50. "sso_account_deactivated.html",
  51. "sso_auth_success.html",
  52. "sso_auth_bad_user.html",
  53. ],
  54. self.sso_template_dir,
  55. )
  56. # These templates have no placeholders, so render them here
  57. self.sso_account_deactivated_template = (
  58. sso_account_deactivated_template.render()
  59. )
  60. self.sso_auth_success_template = sso_auth_success_template.render()
  61. self.sso_client_whitelist = sso_config.get("client_whitelist") or []
  62. # Attempt to also whitelist the server's login fallback, since that fallback sets
  63. # the redirect URL to itself (so it can process the login token then return
  64. # gracefully to the client). This would make it pointless to ask the user for
  65. # confirmation, since the URL the confirmation page would be showing wouldn't be
  66. # the client's.
  67. # public_baseurl is an optional setting, so we only add the fallback's URL to the
  68. # list if it's provided (because we can't figure out what that URL is otherwise).
  69. if self.public_baseurl:
  70. login_fallback_url = self.public_baseurl + "_matrix/static/client/login"
  71. self.sso_client_whitelist.append(login_fallback_url)
  72. def generate_config_section(self, **kwargs):
  73. return """\
  74. # Additional settings to use with single-sign on systems such as OpenID Connect,
  75. # SAML2 and CAS.
  76. #
  77. sso:
  78. # A list of client URLs which are whitelisted so that the user does not
  79. # have to confirm giving access to their account to the URL. Any client
  80. # whose URL starts with an entry in the following list will not be subject
  81. # to an additional confirmation step after the SSO login is completed.
  82. #
  83. # WARNING: An entry such as "https://my.client" is insecure, because it
  84. # will also match "https://my.client.evil.site", exposing your users to
  85. # phishing attacks from evil.site. To avoid this, include a slash after the
  86. # hostname: "https://my.client/".
  87. #
  88. # If public_baseurl is set, then the login fallback page (used by clients
  89. # that don't natively support the required login flows) is whitelisted in
  90. # addition to any URLs in this list.
  91. #
  92. # By default, this list is empty.
  93. #
  94. #client_whitelist:
  95. # - https://riot.im/develop
  96. # - https://my.custom.client/
  97. # Directory in which Synapse will try to find the template files below.
  98. # If not set, or the files named below are not found within the template
  99. # directory, default templates from within the Synapse package will be used.
  100. #
  101. # Synapse will look for the following templates in this directory:
  102. #
  103. # * HTML page to prompt the user to choose an Identity Provider during
  104. # login: 'sso_login_idp_picker.html'.
  105. #
  106. # This is only used if multiple SSO Identity Providers are configured.
  107. #
  108. # When rendering, this template is given the following variables:
  109. # * redirect_url: the URL that the user will be redirected to after
  110. # login.
  111. #
  112. # * server_name: the homeserver's name.
  113. #
  114. # * providers: a list of available Identity Providers. Each element is
  115. # an object with the following attributes:
  116. #
  117. # * idp_id: unique identifier for the IdP
  118. # * idp_name: user-facing name for the IdP
  119. # * idp_icon: if specified in the IdP config, an MXC URI for an icon
  120. # for the IdP
  121. # * idp_brand: if specified in the IdP config, a textual identifier
  122. # for the brand of the IdP
  123. #
  124. # The rendered HTML page should contain a form which submits its results
  125. # back as a GET request, with the following query parameters:
  126. #
  127. # * redirectUrl: the client redirect URI (ie, the `redirect_url` passed
  128. # to the template)
  129. #
  130. # * idp: the 'idp_id' of the chosen IDP.
  131. #
  132. # * HTML page to prompt new users to enter a userid and confirm other
  133. # details: 'sso_auth_account_details.html'. This is only shown if the
  134. # SSO implementation (with any user_mapping_provider) does not return
  135. # a localpart.
  136. #
  137. # When rendering, this template is given the following variables:
  138. #
  139. # * server_name: the homeserver's name.
  140. #
  141. # * idp: details of the SSO Identity Provider that the user logged in
  142. # with: an object with the following attributes:
  143. #
  144. # * idp_id: unique identifier for the IdP
  145. # * idp_name: user-facing name for the IdP
  146. # * idp_icon: if specified in the IdP config, an MXC URI for an icon
  147. # for the IdP
  148. # * idp_brand: if specified in the IdP config, a textual identifier
  149. # for the brand of the IdP
  150. #
  151. # * user_attributes: an object containing details about the user that
  152. # we received from the IdP. May have the following attributes:
  153. #
  154. # * display_name: the user's display_name
  155. # * emails: a list of email addresses
  156. #
  157. # The template should render a form which submits the following fields:
  158. #
  159. # * username: the localpart of the user's chosen user id
  160. #
  161. # * HTML page allowing the user to consent to the server's terms and
  162. # conditions. This is only shown for new users, and only if
  163. # `user_consent.require_at_registration` is set.
  164. #
  165. # When rendering, this template is given the following variables:
  166. #
  167. # * server_name: the homeserver's name.
  168. #
  169. # * user_id: the user's matrix proposed ID.
  170. #
  171. # * user_profile.display_name: the user's proposed display name, if any.
  172. #
  173. # * consent_version: the version of the terms that the user will be
  174. # shown
  175. #
  176. # * terms_url: a link to the page showing the terms.
  177. #
  178. # The template should render a form which submits the following fields:
  179. #
  180. # * accepted_version: the version of the terms accepted by the user
  181. # (ie, 'consent_version' from the input variables).
  182. #
  183. # * HTML page for a confirmation step before redirecting back to the client
  184. # with the login token: 'sso_redirect_confirm.html'.
  185. #
  186. # When rendering, this template is given the following variables:
  187. #
  188. # * redirect_url: the URL the user is about to be redirected to.
  189. #
  190. # * display_url: the same as `redirect_url`, but with the query
  191. # parameters stripped. The intention is to have a
  192. # human-readable URL to show to users, not to use it as
  193. # the final address to redirect to.
  194. #
  195. # * server_name: the homeserver's name.
  196. #
  197. # * new_user: a boolean indicating whether this is the user's first time
  198. # logging in.
  199. #
  200. # * user_id: the user's matrix ID.
  201. #
  202. # * user_profile.avatar_url: an MXC URI for the user's avatar, if any.
  203. # None if the user has not set an avatar.
  204. #
  205. # * user_profile.display_name: the user's display name. None if the user
  206. # has not set a display name.
  207. #
  208. # * HTML page which notifies the user that they are authenticating to confirm
  209. # an operation on their account during the user interactive authentication
  210. # process: 'sso_auth_confirm.html'.
  211. #
  212. # When rendering, this template is given the following variables:
  213. # * redirect_url: the URL the user is about to be redirected to.
  214. #
  215. # * description: the operation which the user is being asked to confirm
  216. #
  217. # * idp: details of the Identity Provider that we will use to confirm
  218. # the user's identity: an object with the following attributes:
  219. #
  220. # * idp_id: unique identifier for the IdP
  221. # * idp_name: user-facing name for the IdP
  222. # * idp_icon: if specified in the IdP config, an MXC URI for an icon
  223. # for the IdP
  224. # * idp_brand: if specified in the IdP config, a textual identifier
  225. # for the brand of the IdP
  226. #
  227. # * HTML page shown after a successful user interactive authentication session:
  228. # 'sso_auth_success.html'.
  229. #
  230. # Note that this page must include the JavaScript which notifies of a successful authentication
  231. # (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
  232. #
  233. # This template has no additional variables.
  234. #
  235. # * HTML page shown after a user-interactive authentication session which
  236. # does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
  237. #
  238. # When rendering, this template is given the following variables:
  239. # * server_name: the homeserver's name.
  240. # * user_id_to_verify: the MXID of the user that we are trying to
  241. # validate.
  242. #
  243. # * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
  244. # attempts to login: 'sso_account_deactivated.html'.
  245. #
  246. # This template has no additional variables.
  247. #
  248. # * HTML page to display to users if something goes wrong during the
  249. # OpenID Connect authentication process: 'sso_error.html'.
  250. #
  251. # When rendering, this template is given two variables:
  252. # * error: the technical name of the error
  253. # * error_description: a human-readable message for the error
  254. #
  255. # You can see the default templates at:
  256. # https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
  257. #
  258. #template_dir: "res/templates"
  259. """