diff --git a/cmd/ft_activity_api/main.go b/cmd/ft_activity_api/main.go index c822026..da34195 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" @@ -9,6 +10,8 @@ import ( "log" "net/http" "os" + "encoding/json" + "strings" ) func main() { @@ -20,6 +23,7 @@ func main() { } router := gin.Default() + router.LoadHTMLGlob("web/templates/*") // CORS Settings @@ -29,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")) } @@ -73,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/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 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 @@ + + + + + + Callback page + + + {{ if .Message }} +

{{ .Message }}

+ {{ end }} + \ No newline at end of file