From d130ee1f3d416e2492a1ff4bef6c1eedda4ad8df Mon Sep 17 00:00:00 2001 From: syamasaw <17191sawa@gmail.com> Date: Wed, 26 Jun 2024 14:04:22 +0900 Subject: [PATCH 1/2] Implementing middleware to verify the API key in the Authorization header --- cmd/ft_activity_api/main.go | 4 ++++ docker-compose.yml | 1 + internal/checkauth/checkauthheader.go | 25 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 internal/checkauth/checkauthheader.go diff --git a/cmd/ft_activity_api/main.go b/cmd/ft_activity_api/main.go index c822026..4e16d8e 100644 --- a/cmd/ft_activity_api/main.go +++ b/cmd/ft_activity_api/main.go @@ -2,6 +2,7 @@ package main import ( "42ActivityAPI/internal/accessdb" + "42ActivityAPI/internal/checkauth" "42ActivityAPI/internal/handlers" "42ActivityAPI/internal/loadconfig" "github.com/gin-contrib/cors" @@ -20,6 +21,9 @@ func main() { } router := gin.Default() + + router.Use(checkauth.CheckAuthHeader()) + router.LoadHTMLGlob("web/templates/*") // CORS Settings diff --git a/docker-compose.yml b/docker-compose.yml index 0a44659..97f71c1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,7 @@ services: CALLBACK_URL: ${CALLBACK_URL} SECRET: ${SECRET} PORT: ${API_PORT} + API_KEY: ${API_KEY} CGO_ENABLED: 1 depends_on: mariadb: diff --git a/internal/checkauth/checkauthheader.go b/internal/checkauth/checkauthheader.go new file mode 100644 index 0000000..de11696 --- /dev/null +++ b/internal/checkauth/checkauthheader.go @@ -0,0 +1,25 @@ +package checkauth + +import ( + "os" + "net/http" + "github.com/gin-gonic/gin" +) +// Validate the API key by matching the environment variables and the Authorization header. +func CheckAuthHeader() gin.HandlerFunc { + return func(c *gin.Context) { + expectedAPIKey := "Bearer " + os.Getenv("API_KEY") + if expectedAPIKey == "Bearer " { + c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error."}) + c.Abort() + return + } + apiKey := c.GetHeader("Authorization") + if apiKey != expectedAPIKey { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + c.Next() + } +} \ No newline at end of file From f65d0a990c586d4208909ecbed00efec78c885d8 Mon Sep 17 00:00:00 2001 From: syamasaw <17191sawa@gmail.com> Date: Wed, 26 Jun 2024 17:10:25 +0900 Subject: [PATCH 2/2] update callback --- cmd/ft_activity_api/main.go | 70 +++++++++++++++++++++++++++++-------- web/templates/response.html | 12 +++++++ 2 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 web/templates/response.html diff --git a/cmd/ft_activity_api/main.go b/cmd/ft_activity_api/main.go index 4e16d8e..da34195 100644 --- a/cmd/ft_activity_api/main.go +++ b/cmd/ft_activity_api/main.go @@ -10,6 +10,8 @@ import ( "log" "net/http" "os" + "encoding/json" + "strings" ) func main() { @@ -22,8 +24,6 @@ func main() { router := gin.Default() - router.Use(checkauth.CheckAuthHeader()) - router.LoadHTMLGlob("web/templates/*") // CORS Settings @@ -33,26 +33,30 @@ func main() { router.GET("/", ShowIndexPage) router.GET("/new", RedirectToIndexWithUID) - router.GET("/callback", ShowCallbackPage) + // router.GET("/callback", ShowCallbackPage) + router.GET("/callback", handleCallback) - router.POST("/receive-uid", handlers.HandleUIDSubmission) + authGroup := router.Group("/", checkauth.CheckAuthHeader()) + { + authGroup.POST("/receive-uid", handlers.HandleUIDSubmission) - router.GET("/shifts", handlers.GetShiftData) - router.POST("/shifts", handlers.AddShiftData) - router.POST("/shifts/exchange", handlers.ExchangeShiftData) - router.DELETE("/shifts", handlers.DeleteShiftData) + authGroup.GET("/shifts", handlers.GetShiftData) + authGroup.POST("/shifts", handlers.AddShiftData) + authGroup.POST("/shifts/exchange", handlers.ExchangeShiftData) + authGroup.DELETE("/shifts", handlers.DeleteShiftData) - router.POST("/activities", handlers.AddActivity) - router.GET("/activities/cleanings", handlers.GetActivityCleanData) + authGroup.POST("/activities", handlers.AddActivity) + authGroup.GET("/activities/cleanings", handlers.GetActivityCleanData) - router.POST("/roles", handlers.AddRole) + authGroup.POST("/roles", handlers.AddRole) - router.POST("/locations", handlers.AddLocation) + authGroup.POST("/locations", handlers.AddLocation) - router.POST("/m5sticks", handlers.AddM5Stick) + authGroup.POST("/m5sticks", handlers.AddM5Stick) - router.POST("/users", handlers.AddUsers) - router.PUT("/users", handlers.EditUser) + authGroup.POST("/users", handlers.AddUsers) + authGroup.PUT("/users", handlers.EditUser) + } router.Run(":" + os.Getenv("PORT")) } @@ -77,3 +81,39 @@ func RedirectToIndexWithUID(c *gin.Context) { func ShowCallbackPage(c *gin.Context) { c.HTML(http.StatusOK, "callback.html", nil) } + +func handleCallback(c *gin.Context) { + uid := c.Query("uid") + code := c.Query("code") + if uid == "" || code == "" { + c.HTML(http.StatusBadRequest, "response.html", gin.H{"Message": "NFCタグとログインの紐付けに失敗しました。管理者に問い合わせてください。"}) + return + } + client := &http.Client{} + data := map[string]string{ "uid": uid, "code": code } + body, err := json.Marshal(data) + if err != nil { + c.HTML(http.StatusInternalServerError, "response.html", gin.H{"Message": "NFCタグとログインの紐付けに失敗しました。管理者に問い合わせてください。"}) + return + } + req, err := http.NewRequest("POST", "http://localhost:4242/receive-uid", strings.NewReader(string(body))) + if err != nil { + c.HTML(http.StatusInternalServerError, "response.html", gin.H{"Message": "NFCタグとログインの紐付けに失敗しました。管理者に問い合わせてください。"}) + return + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer " + os.Getenv("API_KEY")) + res, err := client.Do(req) + if err != nil { + c.HTML(http.StatusInternalServerError, "response.html", gin.H{"Message": "NFCタグとログインの紐付けに失敗しました。管理者に問い合わせてください。"}) + return + } + defer res.Body.Close() + if res.StatusCode == 200 { + c.HTML(http.StatusOK, "response.html", gin.H{"Message": "NFCタグとログインの紐付けが完了しました。ブラウザを閉じてください。"}) + } else if res.StatusCode == 409 { + c.HTML(http.StatusConflict, "response.html", gin.H{"Message": "既に登録されているログインです。ブラウザを閉じてださい。"}) + } else { + c.HTML(res.StatusCode, "response.html", gin.H{"Message": "NFCタグとログインの紐付けに失敗しました。管理者に問い合わせてください。"}) + } +} \ No newline at end of file diff --git a/web/templates/response.html b/web/templates/response.html new file mode 100644 index 0000000..80831d9 --- /dev/null +++ b/web/templates/response.html @@ -0,0 +1,12 @@ + + +
+ + +{{ .Message }}
+ {{ end }} + \ No newline at end of file