From 009e661573ea8531d16cc0cbca955de67e1a8e33 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Sun, 14 Jan 2018 09:33:22 +0000 Subject: [PATCH] Refactor Server.Handler method for readability Should make the subdivision between apps (idp, sso) more obvious. --- server/http.go | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/server/http.go b/server/http.go index a277bf9..52bdbe3 100644 --- a/server/http.go +++ b/server/http.go @@ -295,30 +295,47 @@ func (h *Server) handleExchange(w http.ResponseWriter, req *http.Request) { // Handler returns the http.Handler for the SSO server application. func (h *Server) Handler() http.Handler { - m := mux.NewRouter() + // The root HTTP handler. This must be a gorilla/mux.Router since + // sessions depend on it. + root := mux.NewRouter() - var lih, loh http.Handler - lih = h.loginHandler - loh = h.withAuth(h.handleLogout) - if h.csrfSecret != nil { - csrfW := csrf.Protect(h.csrfSecret) - lih = csrfW(lih) - loh = csrfW(loh) - } - m.Handle("/login", withDynamicHeaders(lih)) - m.Handle("/logout", withDynamicHeaders(loh)) - - m.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(&assetfs.AssetFS{ + // Serve static content to anyone. + root.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(&assetfs.AssetFS{ Asset: Asset, AssetDir: AssetDir, AssetInfo: AssetInfo, Prefix: "static", }))) - m.Handle("/exchange", withDynamicHeaders(http.HandlerFunc(h.handleExchange))) - m.Handle("/", withDynamicHeaders(h.withAuth(h.handleHomepage))) + // Build the main IDP application router, with optional CSRF + // protection. + m := http.NewServeMux() + m.Handle("/login", h.loginHandler) + m.Handle("/logout", h.withAuth(h.handleLogout)) + idph := http.Handler(m) + if h.csrfSecret != nil { + idph = csrf.Protect(h.csrfSecret)(idph) + } + + // Add the SSO provider endpoints (root path and /exchange), + // which do not need CSRF. We use a HandlerFunc to bypass the + // '/' dispatch semantics of the standard http.ServeMux. + ssoh := h.withAuth(h.handleHomepage) + userh := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == "GET" && r.URL.Path == "/": + ssoh.ServeHTTP(w, r) + case r.URL.Path == "/exchange": + h.handleExchange(w, r) + default: + idph.ServeHTTP(w, r) + } + }) - return m + // User-facing routes require cache-busting and CSP headers. + root.PathPrefix("/").Handler(withDynamicHeaders(userh)) + + return root } // A relatively strict CSP. -- GitLab