aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Berwaldt <zberwaldt@tutamail.com>2024-03-07 20:20:36 -0500
committerZach Berwaldt <zberwaldt@tutamail.com>2024-03-07 20:20:36 -0500
commit831b6f0167b9c1747d128b4a5a648d4de42ff0a9 (patch)
tree1042411d1027bdf18a4c8884f595c284e8b5570d
parent29f83e05270d0012ad9f273ac3364106fcff5f50 (diff)
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. ```
-rw-r--r--api/cmd/main.go92
-rw-r--r--api/internal/middleware/middleware.go55
-rw-r--r--api/internal/router/router.go42
3 files changed, 99 insertions, 90 deletions
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 @@
1package main 1package main
2 2
3import ( 3import (
4 "errors"
5 "log"
6 "net/http"
7 "strings"
8 "water/api/internal/database" 4 "water/api/internal/database"
9 "water/api/internal/controllers" 5 "water/api/internal/router"
10
11 "github.com/gin-gonic/gin"
12 _ "github.com/mattn/go-sqlite3"
13) 6)
14 7
15func CORSMiddleware() gin.HandlerFunc {
16 return func(c *gin.Context) {
17 c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
18 c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
19 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")
20 c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
21
22 if c.Request.Method == "OPTIONS" {
23 log.Println(c.Request.Header)
24 c.AbortWithStatus(http.StatusNoContent)
25 return
26 }
27
28 c.Next()
29 }
30}
31
32func checkForTokenInContext(c *gin.Context) (string, error) {
33 authorizationHeader := c.GetHeader("Authorization")
34 if authorizationHeader == "" {
35 return "", errors.New("authorization header is missing")
36 }
37
38 parts := strings.Split(authorizationHeader, " ")
39
40 if len(parts) != 2 || parts[0] != "Bearer" {
41 return "", errors.New("invalid Authorization header format")
42 }
43
44 return parts[1], nil
45}
46
47func TokenRequired() gin.HandlerFunc {
48 return func(c *gin.Context) {
49 _, err := checkForTokenInContext(c)
50
51 if err != nil {
52 c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
53 c.Abort()
54 return
55 }
56
57 c.Next()
58 }
59}
60
61func setupRouter() *gin.Engine {
62 // Disable Console Color
63 // gin.DisableConsoleColor()
64 r := gin.Default()
65 r.Use(CORSMiddleware())
66 r.Use(gin.Logger())
67 r.Use(gin.Recovery())
68
69 api := r.Group("api/v1")
70
71 api.POST("/auth", controllers.AuthHandler)
72
73 user := api.Group("/user/:uuid")
74 user.Use(TokenRequired())
75 {
76 user.GET("", controllers.GetUser)
77 user.GET("preferences", controllers.GetUserPreferences)
78 user.PATCH("preferences", controllers.UpdateUserPreferences)
79 }
80
81 stats := api.Group("/stats")
82 stats.Use(TokenRequired())
83 {
84 stats.GET("/", controllers.GetAllStatistics)
85 stats.POST("/", controllers.PostNewStatistic)
86 stats.GET("weekly/", controllers.GetWeeklyStatistics)
87 stats.GET("daily/", controllers.GetDailyUserStatistics)
88 stats.GET("user/:uuid", controllers.GetUserStatistics)
89 stats.PATCH("user/:uuid", controllers.UpdateUserStatistic)
90 stats.DELETE("user/:uuid", controllers.DeleteUserStatistic)
91 }
92
93 return r
94}
95
96func main() { 8func main() {
97 database.SetupDatabase() 9 database.SetupDatabase()
98 r := setupRouter() 10 r := router.SetupRouter()
99 // Listen and Server in 0.0.0.0:8080 11 // Listen and Server in 0.0.0.0:8080
100 err := r.Run(":8080") 12 err := r.Run(":8080")
101 if err != nil { 13 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 @@
1package middleware
2
3import (
4 "errors"
5 "github.com/gin-gonic/gin"
6 "log"
7 "net/http"
8 "strings"
9)
10
11func TokenRequired() gin.HandlerFunc {
12 return func(c *gin.Context) {
13 _, err := checkForTokenInContext(c)
14
15 if err != nil {
16 c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
17 c.Abort()
18 return
19 }
20
21 c.Next()
22 }
23}
24
25func CORSMiddleware() gin.HandlerFunc {
26 return func(c *gin.Context) {
27 c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
28 c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
29 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")
30 c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
31
32 if c.Request.Method == "OPTIONS" {
33 log.Println(c.Request.Header)
34 c.AbortWithStatus(http.StatusNoContent)
35 return
36 }
37
38 c.Next()
39 }
40}
41
42func checkForTokenInContext(c *gin.Context) (string, error) {
43 authorizationHeader := c.GetHeader("Authorization")
44 if authorizationHeader == "" {
45 return "", errors.New("authorization header is missing")
46 }
47
48 parts := strings.Split(authorizationHeader, " ")
49
50 if len(parts) != 2 || parts[0] != "Bearer" {
51 return "", errors.New("invalid Authorization header format")
52 }
53
54 return parts[1], nil
55} \ 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 @@
1package router
2
3import (
4 "github.com/gin-gonic/gin"
5 "water/api/internal/controllers"
6 "water/api/internal/middleware"
7)
8
9func SetupRouter() *gin.Engine {
10 // Disable Console Color
11 // gin.DisableConsoleColor()
12 r := gin.Default()
13 r.Use(middleware.CORSMiddleware())
14 r.Use(gin.Logger())
15 r.Use(gin.Recovery())
16
17 api := r.Group("api/v1")
18
19 api.POST("/auth", controllers.AuthHandler)
20
21 user := api.Group("/user/:uuid")
22 user.Use(middleware.TokenRequired())
23 {
24 user.GET("", controllers.GetUser)
25 user.GET("preferences", controllers.GetUserPreferences)
26 user.PATCH("preferences", controllers.UpdateUserPreferences)
27 }
28
29 stats := api.Group("/stats")
30 stats.Use(middleware.TokenRequired())
31 {
32 stats.GET("/", controllers.GetAllStatistics)
33 stats.POST("/", controllers.PostNewStatistic)
34 stats.GET("weekly/", controllers.GetWeeklyStatistics)
35 stats.GET("daily/", controllers.GetDailyUserStatistics)
36 stats.GET("user/:uuid", controllers.GetUserStatistics)
37 stats.PATCH("user/:uuid", controllers.UpdateUserStatistic)
38 stats.DELETE("user/:uuid", controllers.DeleteUserStatistic)
39 }
40
41 return r
42} \ No newline at end of file