summary refs log tree commit diff
path: root/synapse/rest/client/v1/login.py
diff options
context:
space:
mode:
authorBrendan Abolivier <babolivier@matrix.org>2020-03-02 16:36:32 +0000
committerBrendan Abolivier <babolivier@matrix.org>2020-03-02 16:36:32 +0000
commitb2bd54a2e31d9a248f73fadb184ae9b4cbdb49f9 (patch)
tree409b30e1dfc1bfd0951e5497a9fce4bb6418ce5a /synapse/rest/client/v1/login.py
parentCast a coroutine into a Deferred in the federation base (#6996) (diff)
downloadsynapse-b2bd54a2e31d9a248f73fadb184ae9b4cbdb49f9.tar.xz
Add a confirmation step to the SSO login flow
Diffstat (limited to 'synapse/rest/client/v1/login.py')
-rw-r--r--synapse/rest/client/v1/login.py40
1 files changed, 34 insertions, 6 deletions
diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py
index 1294e080dc..1acfd01d8e 100644
--- a/synapse/rest/client/v1/login.py
+++ b/synapse/rest/client/v1/login.py
@@ -29,6 +29,7 @@ from synapse.http.servlet import (
     parse_string,
 )
 from synapse.http.site import SynapseRequest
+from synapse.push.mailer import load_jinja2_templates
 from synapse.rest.client.v2_alpha._base import client_patterns
 from synapse.rest.well_known import WellKnownBuilder
 from synapse.types import UserID, map_username_to_mxid_localpart
@@ -548,6 +549,13 @@ class SSOAuthHandler(object):
         self._registration_handler = hs.get_registration_handler()
         self._macaroon_gen = hs.get_macaroon_generator()
 
+        # Load the redirect page HTML template
+        self._template = load_jinja2_templates(
+            hs.config.sso_redirect_confirm_template_dir, ["sso_redirect_confirm.html"],
+        )[0]
+
+        self._server_name = hs.config.server_name
+
     async def on_successful_auth(
         self, username, request, client_redirect_url, user_display_name=None
     ):
@@ -592,21 +600,41 @@ class SSOAuthHandler(object):
             request:
             client_redirect_url:
         """
-
+        # Create a login token
         login_token = self._macaroon_gen.generate_short_term_login_token(
             registered_user_id
         )
-        redirect_url = self._add_login_token_to_redirect_url(
-            client_redirect_url, login_token
+
+        # Remove the query parameters from the redirect URL to get a shorter version of
+        # it. This is only to display a human-readable URL in the template, but not the
+        # URL we redirect users to.
+        redirect_url_no_params = client_redirect_url.split("?")[0]
+
+        # Append the login token to the original redirect URL (i.e. with its query
+        # parameters kept intact) to build the URL to which the template needs to
+        # redirect the users once they have clicked on the confirmation link.
+        redirect_url = self._add_query_param_to_url(
+            client_redirect_url, "loginToken", login_token
+        )
+
+        # Serve the redirect confirmation page
+        html = self._template.render(
+            display_url=redirect_url_no_params,
+            redirect_url=redirect_url,
+            server_name=self._server_name,
         )
-        request.redirect(redirect_url)
+
+        request.setResponseCode(200)
+        request.setHeader(b"Content-Type", b"text/html; charset=utf-8")
+        request.setHeader(b"Content-Length", b"%d" % (len(html),))
+        request.write(html.encode("utf8"))
         finish_request(request)
 
     @staticmethod
-    def _add_login_token_to_redirect_url(url, token):
+    def _add_query_param_to_url(url, param_name, param):
         url_parts = list(urllib.parse.urlparse(url))
         query = dict(urllib.parse.parse_qsl(url_parts[4]))
-        query.update({"loginToken": token})
+        query.update({param_name: param})
         url_parts[4] = urllib.parse.urlencode(query)
         return urllib.parse.urlunparse(url_parts)