aboutsummaryrefslogtreecommitdiff
path: root/cmd/server/middleware.go
diff options
context:
space:
mode:
authorMitchell Riedstra <mitch@riedstra.dev>2022-09-17 11:41:20 -0400
committerMitchell Riedstra <mitch@riedstra.dev>2022-09-17 11:41:20 -0400
commitccc26c3a0bb65ae2613e222c3ead7f6db377b483 (patch)
tree6124ae75f557fffe863134b967ee7c6bfcc87d3d /cmd/server/middleware.go
parentbf7d9c79cae53f64fcd04527248987bd4e7ca3c4 (diff)
downloadgo-website-ccc26c3a0bb65ae2613e222c3ead7f6db377b483.tar.gz
go-website-ccc26c3a0bb65ae2613e222c3ead7f6db377b483.tar.xz
More work on the editor and update the example site to utilize it.v0.0.18
Diffstat (limited to 'cmd/server/middleware.go')
-rw-r--r--cmd/server/middleware.go114
1 files changed, 85 insertions, 29 deletions
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)
+ }
}
+*/