]> git.ipfire.org Git - ipfire.org.git/commitdiff
people: Move SSO for Discourse
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 26 Jun 2023 09:47:19 +0000 (09:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 26 Jun 2023 09:48:16 +0000 (09:48 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/web/__init__.py
src/web/auth.py
src/web/people.py

index 6b0e2b8dac7261efbc21a94d6a9b77efde35d404..732fd5a5ba2477598dec0ce04fb062aa5bb61078 100644 (file)
@@ -156,6 +156,9 @@ class Application(tornado.web.Application):
                        (r"/password\-reset", auth.PasswordResetInitiationHandler),
                        (r"/password\-reset/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.PasswordResetHandler),
 
+                       # Single-Sign-On for Discourse
+                       (r"/sso/discourse", auth.SSODiscourse),
+
                        # User Groups
                        (r"/users/groups", users.GroupIndexHandler),
                        (r"/users/groups/([a-z_][a-z0-9_-]{0,31})", users.GroupShowHandler),
@@ -322,9 +325,6 @@ class Application(tornado.web.Application):
                        (r"/subscribe", people.SubscribeHandler),
                        (r"/unsubscribe", people.UnsubscribeHandler),
 
-                       # Single-Sign-On for Discourse
-                       (r"/sso/discourse", people.SSODiscourse),
-
                        # Serve any static files
                        (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
 
index d633a94b2e0603186f0450700c49469d7bba3d63..792205feb40030e1e700abbfd78c1aab0fce4d65 100644 (file)
@@ -2,6 +2,7 @@
 
 import logging
 import tornado.web
+import urllib.parse
 
 from . import base
 
@@ -193,6 +194,61 @@ class PasswordResetHandler(AuthenticationMixin, base.BaseHandler):
                self.redirect("/")
 
 
+class SSODiscourse(CacheMixin, base.BaseHandler):
+       @base.ratelimit(minutes=24*60, requests=100)
+       @tornado.web.authenticated
+       def get(self):
+               # Fetch Discourse's parameters
+               sso = self.get_argument("sso")
+               sig = self.get_argument("sig")
+
+               # Decode payload
+               try:
+                       params = self.accounts.decode_discourse_payload(sso, sig)
+
+               # Raise bad request if the signature is invalid
+               except ValueError:
+                       raise tornado.web.HTTPError(400)
+
+               # Redirect back if user is already logged in
+               args = {
+                       "nonce" : params.get("nonce"),
+                       "external_id" : self.current_user.uid,
+
+                       # Pass email address
+                       "email" : self.current_user.email,
+                       "require_activation" : "false",
+
+                       # More details about the user
+                       "username" : self.current_user.uid,
+                       "name" : "%s" % self.current_user,
+                       "bio" : self.current_user.description or "",
+
+                       # Avatar
+                       "avatar_url" : self.current_user.avatar_url(absolute=True),
+                       "avatar_force_update" : "true",
+
+                       # Send a welcome message
+                       "suppress_welcome_message" : "false",
+
+                       # Group memberships
+                       "admin" : "true" if self.current_user.is_admin() else "false",
+                       "moderator" : "true" if self.current_user.is_moderator() else "false",
+               }
+
+               # Format payload and sign it
+               payload = self.accounts.encode_discourse_payload(**args)
+               signature = self.accounts.sign_discourse_payload(payload)
+
+               qs = urllib.parse.urlencode({
+                       "sso" : payload,
+                       "sig" : signature,
+               })
+
+               # Redirect user
+               self.redirect("%s?%s" % (params.get("return_sso_url"), qs))
+
+
 class APICheckUID(base.APIHandler):
        @base.ratelimit(minutes=1, requests=100)
        def get(self):
index a0174c26f69df551bf66bc68681f45538f7c5617..5cc0c8c7517f90af25bc1694ee6f70ceb3f50d57 100644 (file)
@@ -3,7 +3,6 @@
 import datetime
 import ldap
 import tornado.web
-import urllib.parse
 
 from .. import countries
 
@@ -209,61 +208,6 @@ class UserPasswdHandler(auth.CacheMixin, base.BaseHandler):
                self.redirect("/users/%s" % account.uid)
 
 
-class SSODiscourse(auth.CacheMixin, base.BaseHandler):
-       @base.ratelimit(minutes=24*60, requests=100)
-       @tornado.web.authenticated
-       def get(self):
-               # Fetch Discourse's parameters
-               sso = self.get_argument("sso")
-               sig = self.get_argument("sig")
-
-               # Decode payload
-               try:
-                       params = self.accounts.decode_discourse_payload(sso, sig)
-
-               # Raise bad request if the signature is invalid
-               except ValueError:
-                       raise tornado.web.HTTPError(400)
-
-               # Redirect back if user is already logged in
-               args = {
-                       "nonce" : params.get("nonce"),
-                       "external_id" : self.current_user.uid,
-
-                       # Pass email address
-                       "email" : self.current_user.email,
-                       "require_activation" : "false",
-
-                       # More details about the user
-                       "username" : self.current_user.uid,
-                       "name" : "%s" % self.current_user,
-                       "bio" : self.current_user.description or "",
-
-                       # Avatar
-                       "avatar_url" : self.current_user.avatar_url(absolute=True),
-                       "avatar_force_update" : "true",
-
-                       # Send a welcome message
-                       "suppress_welcome_message" : "false",
-
-                       # Group memberships
-                       "admin" : "true" if self.current_user.is_admin() else "false",
-                       "moderator" : "true" if self.current_user.is_moderator() else "false",
-               }
-
-               # Format payload and sign it
-               payload = self.accounts.encode_discourse_payload(**args)
-               signature = self.accounts.sign_discourse_payload(payload)
-
-               qs = urllib.parse.urlencode({
-                       "sso" : payload,
-                       "sig" : signature,
-               })
-
-               # Redirect user
-               self.redirect("%s?%s" % (params.get("return_sso_url"), qs))
-
-
 class AgentModule(ui_modules.UIModule):
        def render(self, account):
                return self.render_string("people/modules/agent.html", account=account)