From ccc26c3a0bb65ae2613e222c3ead7f6db377b483 Mon Sep 17 00:00:00 2001 From: Mitchell Riedstra Date: Sat, 17 Sep 2022 11:41:20 -0400 Subject: More work on the editor and update the example site to utilize it. --- cmd/server/middleware.go | 114 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 29 deletions(-) (limited to 'cmd/server/middleware.go') diff --git a/cmd/server/middleware.go b/cmd/server/middleware.go index 5e4bf26..0d332cd 100644 --- a/cmd/server/middleware.go +++ b/cmd/server/middleware.go @@ -1,8 +1,10 @@ package main import ( + "errors" "log" "net/http" + "net/url" "time" jwt "github.com/dgrijalva/jwt-go" @@ -30,27 +32,41 @@ func (a *App) LogoutHandler(w http.ResponseWriter, r *http.Request) { SameSite: a.auth.SameSiteStrict, Secure: a.auth.Secure, Value: "logout", - Expires: time.Now().Add(time.Second * 15), //nolint + Expires: time.Now().Add(time.Second), //nolint }) http.Redirect(w, r, "/", http.StatusFound) } func (a *App) LoginHandler(w http.ResponseWriter, r *http.Request) { //nolint - if r.Method == "GET" { + loggedIn := a.IsLoggedIn(r) + + next, _ := url.Parse(r.URL.Query().Get("next")) + + if r.Method == "GET" && !loggedIn { page.RenderForPath(w, r, "login") return } + if r.Method == "GET" && loggedIn { + if next.Path != "" { + http.Redirect(w, r, next.Path, http.StatusFound) + + return + } + + http.Redirect(w, r, "/dashboard", http.StatusFound) + + return + } + if r.Method != "POST" { a.Err500Default(w, r) return } - log.Printf("made it") - username := r.FormValue("username") password := r.FormValue("password") @@ -90,8 +106,6 @@ func (a *App) LoginHandler(w http.ResponseWriter, r *http.Request) { //nolint return } - log.Println(ss) - http.SetCookie(w, &http.Cookie{ Name: "Auth", HttpOnly: a.auth.HTTPOnly, @@ -103,40 +117,82 @@ func (a *App) LoginHandler(w http.ResponseWriter, r *http.Request) { //nolint http.Redirect(w, r, "/login", http.StatusFound) } +func (a *App) IsLoggedIn(r *http.Request) bool { + _, err := a.GetAuthToken(r) + if err != nil { + log.Printf("%s IsLoggedIn: false", r.URL.Path) + return false + } + log.Printf("%s IsLoggedIn: true", r.URL.Path) + return true +} + +func (a *App) GetAuthToken(r *http.Request) (*jwt.Token, error) { + c, err := r.Cookie("Auth") + if err != nil { + return nil, err + } + + token, err := jwt.Parse(c.Value, + func(token *jwt.Token) (interface{}, error) { + return []byte(a.auth.TokenKey), nil + }, + ) + + if err != nil { + return nil, err + } + + if !token.Valid { + return token, errors.New("IsLoggedIn: token not valid") + } + + return token, nil +} + func (a *App) RequiresLogin(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mustLoginResp := func() { + + if !a.IsLoggedIn(r) { + log.Printf("Unauthorized request %s %s", r.Method, r.URL.Path) page.Render(w, r, "login", map[string]interface{}{ "Error": "You must login to view this page", }, http.StatusUnauthorized) - } - - c, err := r.Cookie("Auth") - if err != nil { - mustLoginResp() return } - token, err := jwt.Parse(c.Value, - func(token *jwt.Token) (interface{}, error) { - return []byte(a.auth.TokenKey), nil - }, - ) - - if err != nil { - log.Printf("Unauthorized request %s %s", r.Method, r.URL.Path) - mustLoginResp() + next.ServeHTTP(w, r) - return - } + }) +} - if !token.Valid { - mustLoginResp() +/* +// ConditionalMiddleware is used to select one handler or another based on +// a test function. If the test function returns true, use handler A, otherwise B. +// This allows the test condition to only be run when the handler is selected +// rather than trying to do this as a top level and ending up with a condition +// that is tested on every single request, regardless of whether or not +// the specific handler is selected +type ConditionalMiddleware struct { + A, B http.Handler + Test func(r *http.Request) bool +} - return - } +func NewConditionalMiddleware(test func(r *http.Request) bool, + A, B http.Handler) http.Handler { + return &ConditionalMiddleware{ + Test: test, + A: A, + B: B, + } +} - next.ServeHTTP(w, r) - }) +func (cm *ConditionalMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if cm.Test(r) { + cm.A.ServeHTTP(w, r) + } else { + cm.B.ServeHTTP(w, r) + } } +*/ -- cgit v1.2.3