From 3d80b95f55b56988bb4e4328b68510f4a03d5dd9 Mon Sep 17 00:00:00 2001 From: Maximilian Date: Fri, 7 Jul 2023 18:05:17 -0500 Subject: [PATCH 1/6] Initial wrapper implementation --- middleware/wrapper.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 middleware/wrapper.go diff --git a/middleware/wrapper.go b/middleware/wrapper.go new file mode 100644 index 0000000..05d67d9 --- /dev/null +++ b/middleware/wrapper.go @@ -0,0 +1,13 @@ +package middleware + +import "net/http" + +// ProcessMiddleware is a wrapper function for the http.HandleFunc function +// that takes the function you want to execute (f) and the middleware you want to execute (m) +func ProcessMiddleware(f func(w http.ResponseWriter, r *http.Request), m []func()) func(w http.ResponseWriter, r *http.Request) { + for _, middleware := range m { + middleware() + } + + return f +} From 05397c2b6127ab94e3283ba21c67922bd392ed13 Mon Sep 17 00:00:00 2001 From: Maximilian Date: Fri, 21 Jul 2023 11:59:01 -0500 Subject: [PATCH 2/6] Initial middleware implementation for CSRF and update comment --- middleware/csrf.go | 22 ++++++++++++++++++++++ middleware/wrapper.go | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 middleware/csrf.go diff --git a/middleware/csrf.go b/middleware/csrf.go new file mode 100644 index 0000000..544c0c3 --- /dev/null +++ b/middleware/csrf.go @@ -0,0 +1,22 @@ +package middleware + +import ( + "GoWeb/security" + "log" + "net/http" +) + +// CsrfMiddleware validates the CSRF token and returns the handler function if it succeded +func CsrfMiddleware(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + // Verify csrf token + _, err := security.VerifyCsrfToken(r) + if err != nil { + log.Println("Error verifying csrf token") + http.Error(w, "Forbidden", http.StatusForbidden) + return + } + + f(w, r) + } +} diff --git a/middleware/wrapper.go b/middleware/wrapper.go index 05d67d9..e315c1c 100644 --- a/middleware/wrapper.go +++ b/middleware/wrapper.go @@ -3,7 +3,8 @@ package middleware import "net/http" // ProcessMiddleware is a wrapper function for the http.HandleFunc function -// that takes the function you want to execute (f) and the middleware you want to execute (m) +// that takes the function you want to execute (f) and the middleware you want +// to execute (m) this should be used when processing multiple groups of middleware at a time func ProcessMiddleware(f func(w http.ResponseWriter, r *http.Request), m []func()) func(w http.ResponseWriter, r *http.Request) { for _, middleware := range m { middleware() From bada24884a5df2dc36ab1022d914721ffb98f4b7 Mon Sep 17 00:00:00 2001 From: Maximilian Date: Fri, 21 Jul 2023 11:59:55 -0500 Subject: [PATCH 3/6] Use ungrouped CSRF middleware on register and login POST routes --- controllers/postController.go | 19 ++----------------- routes/postRoutes.go | 5 +++-- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/controllers/postController.go b/controllers/postController.go index f0af29d..1631f98 100644 --- a/controllers/postController.go +++ b/controllers/postController.go @@ -3,7 +3,6 @@ package controllers import ( "GoWeb/app" "GoWeb/models" - "GoWeb/security" "log" "net/http" "time" @@ -15,13 +14,6 @@ type PostController struct { } func (postController *PostController) Login(w http.ResponseWriter, r *http.Request) { - // Validate csrf token - _, err := security.VerifyCsrfToken(r) - if err != nil { - log.Println("Error verifying csrf token") - return - } - username := r.FormValue("username") password := r.FormValue("password") remember := r.FormValue("remember") == "on" @@ -31,7 +23,7 @@ func (postController *PostController) Login(w http.ResponseWriter, r *http.Reque http.Redirect(w, r, "/login", http.StatusFound) } - _, err = models.AuthenticateUser(postController.App, w, username, password, remember) + _, err := models.AuthenticateUser(postController.App, w, username, password, remember) if err != nil { log.Println("Error authenticating user") log.Println(err) @@ -43,13 +35,6 @@ func (postController *PostController) Login(w http.ResponseWriter, r *http.Reque } func (postController *PostController) Register(w http.ResponseWriter, r *http.Request) { - // Validate csrf token - _, err := security.VerifyCsrfToken(r) - if err != nil { - log.Println("Error verifying csrf token") - return - } - username := r.FormValue("username") password := r.FormValue("password") createdAt := time.Now() @@ -60,7 +45,7 @@ func (postController *PostController) Register(w http.ResponseWriter, r *http.Re http.Redirect(w, r, "/register", http.StatusFound) } - _, err = models.CreateUser(postController.App, username, password, createdAt, updatedAt) + _, err := models.CreateUser(postController.App, username, password, createdAt, updatedAt) if err != nil { log.Println("Error creating user") log.Println(err) diff --git a/routes/postRoutes.go b/routes/postRoutes.go index 58ab50e..d076cf7 100644 --- a/routes/postRoutes.go +++ b/routes/postRoutes.go @@ -3,6 +3,7 @@ package routes import ( "GoWeb/app" "GoWeb/controllers" + "GoWeb/middleware" "net/http" ) @@ -14,6 +15,6 @@ func PostRoutes(app *app.App) { } // User authentication - http.HandleFunc("/register-handle", postController.Register) - http.HandleFunc("/login-handle", postController.Login) + http.HandleFunc("/register-handle", middleware.CsrfMiddleware(postController.Register)) + http.HandleFunc("/login-handle", middleware.CsrfMiddleware(postController.Login)) } From eb36156c5227be0c676ffd2f46067579d9847a27 Mon Sep 17 00:00:00 2001 From: Maximilian Date: Fri, 21 Jul 2023 16:26:43 -0500 Subject: [PATCH 4/6] Change function name to ProcessGroup --- middleware/wrapper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/middleware/wrapper.go b/middleware/wrapper.go index e315c1c..b75ab6b 100644 --- a/middleware/wrapper.go +++ b/middleware/wrapper.go @@ -2,10 +2,10 @@ package middleware import "net/http" -// ProcessMiddleware is a wrapper function for the http.HandleFunc function +// ProcessGroup is a wrapper function for the http.HandleFunc function // that takes the function you want to execute (f) and the middleware you want // to execute (m) this should be used when processing multiple groups of middleware at a time -func ProcessMiddleware(f func(w http.ResponseWriter, r *http.Request), m []func()) func(w http.ResponseWriter, r *http.Request) { +func ProcessGroup(f func(w http.ResponseWriter, r *http.Request), m []func()) func(w http.ResponseWriter, r *http.Request) { for _, middleware := range m { middleware() } From 606f5df45a550e0a424294d500b538daf7cb294f Mon Sep 17 00:00:00 2001 From: Maximilian Date: Sat, 22 Jul 2023 23:37:38 -0500 Subject: [PATCH 5/6] Refactor name --- middleware/csrf.go | 4 ++-- routes/postRoutes.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/middleware/csrf.go b/middleware/csrf.go index 544c0c3..de3c04c 100644 --- a/middleware/csrf.go +++ b/middleware/csrf.go @@ -6,8 +6,8 @@ import ( "net/http" ) -// CsrfMiddleware validates the CSRF token and returns the handler function if it succeded -func CsrfMiddleware(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { +// Csrf validates the CSRF token and returns the handler function if it succeded +func Csrf(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // Verify csrf token _, err := security.VerifyCsrfToken(r) diff --git a/routes/postRoutes.go b/routes/postRoutes.go index d076cf7..a0d93b1 100644 --- a/routes/postRoutes.go +++ b/routes/postRoutes.go @@ -15,6 +15,6 @@ func PostRoutes(app *app.App) { } // User authentication - http.HandleFunc("/register-handle", middleware.CsrfMiddleware(postController.Register)) - http.HandleFunc("/login-handle", middleware.CsrfMiddleware(postController.Login)) + http.HandleFunc("/register-handle", middleware.Csrf(postController.Register)) + http.HandleFunc("/login-handle", middleware.Csrf(postController.Login)) } From f1fad7e4e33e8f8e030413b6a5916bc06278e301 Mon Sep 17 00:00:00 2001 From: Maximilian Date: Mon, 31 Jul 2023 18:37:54 -0500 Subject: [PATCH 6/6] Pass in handler to middleware, create definition for MiddlewareFunc --- middleware/groups.go | 5 +++++ middleware/wrapper.go | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 middleware/groups.go diff --git a/middleware/groups.go b/middleware/groups.go new file mode 100644 index 0000000..0bb20a4 --- /dev/null +++ b/middleware/groups.go @@ -0,0 +1,5 @@ +package middleware + +import "net/http" + +type MiddlewareFunc func(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) diff --git a/middleware/wrapper.go b/middleware/wrapper.go index b75ab6b..ce0d4e6 100644 --- a/middleware/wrapper.go +++ b/middleware/wrapper.go @@ -5,9 +5,9 @@ import "net/http" // ProcessGroup is a wrapper function for the http.HandleFunc function // that takes the function you want to execute (f) and the middleware you want // to execute (m) this should be used when processing multiple groups of middleware at a time -func ProcessGroup(f func(w http.ResponseWriter, r *http.Request), m []func()) func(w http.ResponseWriter, r *http.Request) { +func ProcessGroup(f func(w http.ResponseWriter, r *http.Request), m []MiddlewareFunc) func(w http.ResponseWriter, r *http.Request) { for _, middleware := range m { - middleware() + _ = middleware(f) } return f