From 831b6f0167b9c1747d128b4a5a648d4de42ff0a9 Mon Sep 17 00:00:00 2001 From: Zach Berwaldt Date: Thu, 7 Mar 2024 20:20:36 -0500 Subject: Refactor router and middleware packages - Move middleware functions from `main.go` to `middleware.go` in the `middleware` package. - Update import statements in `main.go` and use the `router` package instead of the `controllers` package. ``` Refactor router and middleware packages Move middleware functions from `main.go` to `middleware.go` in the `middleware` package. Update import statements in `main.go` and use the `router` package instead of the `controllers` package. ``` --- api/cmd/main.go | 92 +---------------------------------- api/internal/middleware/middleware.go | 55 +++++++++++++++++++++ api/internal/router/router.go | 42 ++++++++++++++++ 3 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 api/internal/middleware/middleware.go create mode 100644 api/internal/router/router.go diff --git a/api/cmd/main.go b/api/cmd/main.go index 1924556..d97c942 100644 --- a/api/cmd/main.go +++ b/api/cmd/main.go @@ -1,101 +1,13 @@ package main import ( - "errors" - "log" - "net/http" - "strings" "water/api/internal/database" - "water/api/internal/controllers" - - "github.com/gin-gonic/gin" - _ "github.com/mattn/go-sqlite3" + "water/api/internal/router" ) -func CORSMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") - c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") - c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") - - if c.Request.Method == "OPTIONS" { - log.Println(c.Request.Header) - c.AbortWithStatus(http.StatusNoContent) - return - } - - c.Next() - } -} - -func checkForTokenInContext(c *gin.Context) (string, error) { - authorizationHeader := c.GetHeader("Authorization") - if authorizationHeader == "" { - return "", errors.New("authorization header is missing") - } - - parts := strings.Split(authorizationHeader, " ") - - if len(parts) != 2 || parts[0] != "Bearer" { - return "", errors.New("invalid Authorization header format") - } - - return parts[1], nil -} - -func TokenRequired() gin.HandlerFunc { - return func(c *gin.Context) { - _, err := checkForTokenInContext(c) - - if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) - c.Abort() - return - } - - c.Next() - } -} - -func setupRouter() *gin.Engine { - // Disable Console Color - // gin.DisableConsoleColor() - r := gin.Default() - r.Use(CORSMiddleware()) - r.Use(gin.Logger()) - r.Use(gin.Recovery()) - - api := r.Group("api/v1") - - api.POST("/auth", controllers.AuthHandler) - - user := api.Group("/user/:uuid") - user.Use(TokenRequired()) - { - user.GET("", controllers.GetUser) - user.GET("preferences", controllers.GetUserPreferences) - user.PATCH("preferences", controllers.UpdateUserPreferences) - } - - stats := api.Group("/stats") - stats.Use(TokenRequired()) - { - stats.GET("/", controllers.GetAllStatistics) - stats.POST("/", controllers.PostNewStatistic) - stats.GET("weekly/", controllers.GetWeeklyStatistics) - stats.GET("daily/", controllers.GetDailyUserStatistics) - stats.GET("user/:uuid", controllers.GetUserStatistics) - stats.PATCH("user/:uuid", controllers.UpdateUserStatistic) - stats.DELETE("user/:uuid", controllers.DeleteUserStatistic) - } - - return r -} - func main() { database.SetupDatabase() - r := setupRouter() + r := router.SetupRouter() // Listen and Server in 0.0.0.0:8080 err := r.Run(":8080") if err != nil { diff --git a/api/internal/middleware/middleware.go b/api/internal/middleware/middleware.go new file mode 100644 index 0000000..819f1e5 --- /dev/null +++ b/api/internal/middleware/middleware.go @@ -0,0 +1,55 @@ +package middleware + +import ( + "errors" + "github.com/gin-gonic/gin" + "log" + "net/http" + "strings" +) + +func TokenRequired() gin.HandlerFunc { + return func(c *gin.Context) { + _, err := checkForTokenInContext(c) + + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + + c.Next() + } +} + +func CORSMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") + c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") + + if c.Request.Method == "OPTIONS" { + log.Println(c.Request.Header) + c.AbortWithStatus(http.StatusNoContent) + return + } + + c.Next() + } +} + +func checkForTokenInContext(c *gin.Context) (string, error) { + authorizationHeader := c.GetHeader("Authorization") + if authorizationHeader == "" { + return "", errors.New("authorization header is missing") + } + + parts := strings.Split(authorizationHeader, " ") + + if len(parts) != 2 || parts[0] != "Bearer" { + return "", errors.New("invalid Authorization header format") + } + + return parts[1], nil +} \ No newline at end of file diff --git a/api/internal/router/router.go b/api/internal/router/router.go new file mode 100644 index 0000000..adf96d0 --- /dev/null +++ b/api/internal/router/router.go @@ -0,0 +1,42 @@ +package router + +import ( + "github.com/gin-gonic/gin" + "water/api/internal/controllers" + "water/api/internal/middleware" +) + +func SetupRouter() *gin.Engine { + // Disable Console Color + // gin.DisableConsoleColor() + r := gin.Default() + r.Use(middleware.CORSMiddleware()) + r.Use(gin.Logger()) + r.Use(gin.Recovery()) + + api := r.Group("api/v1") + + api.POST("/auth", controllers.AuthHandler) + + user := api.Group("/user/:uuid") + user.Use(middleware.TokenRequired()) + { + user.GET("", controllers.GetUser) + user.GET("preferences", controllers.GetUserPreferences) + user.PATCH("preferences", controllers.UpdateUserPreferences) + } + + stats := api.Group("/stats") + stats.Use(middleware.TokenRequired()) + { + stats.GET("/", controllers.GetAllStatistics) + stats.POST("/", controllers.PostNewStatistic) + stats.GET("weekly/", controllers.GetWeeklyStatistics) + stats.GET("daily/", controllers.GetDailyUserStatistics) + stats.GET("user/:uuid", controllers.GetUserStatistics) + stats.PATCH("user/:uuid", controllers.UpdateUserStatistic) + stats.DELETE("user/:uuid", controllers.DeleteUserStatistic) + } + + return r +} \ No newline at end of file -- cgit v1.1