From 0556bc49327225ac53d99e2222d8de9dfa73ee35da5aa4ae739617ea37190538 Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Thu, 23 Apr 2026 15:43:39 +0200 Subject: [PATCH] chore: reorder api package structure --- internal/api/api.go | 16 ++++--------- internal/api/middleware/middleware.go | 20 +++++++++++++--- internal/api/response/response.go | 11 +++++++++ internal/api/{routes_api.go => routes/api.go} | 21 +++++++++-------- .../api/{routes_file.go => routes/file.go} | 23 ++++++++++--------- internal/database/define.go | 4 +--- 6 files changed, 56 insertions(+), 39 deletions(-) create mode 100644 internal/api/response/response.go rename internal/api/{routes_api.go => routes/api.go} (59%) rename internal/api/{routes_file.go => routes/file.go} (73%) diff --git a/internal/api/api.go b/internal/api/api.go index cf8a7fa..752b972 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -3,23 +3,15 @@ package api import ( "fmt" "log/slog" + "orbits-server/internal/api/middleware" + "orbits-server/internal/api/routes" "orbits-server/internal/utility" "github.com/gin-gonic/gin" "gorm.io/gorm" ) -const ( - okMes string = "OK" - ieMes string = "An internal error occured, contact your administrator" -) - -type RespObj struct { - Msg string `json:"msg"` - Data any `json:"data"` -} - // All error messages from slog must have an error field with the golang error // See bottom the the kickoff function for details @@ -34,10 +26,10 @@ func KickoffApi(logger *slog.Logger, env utility.Environment, db *gorm.DB) { r.Use(gin.Recovery()) api := r.Group("/api") - spawnApiRoutes(api /*env,*/, db) + routes.RegisterApiRoutes(api /*env,*/, db) file := r.Group("/file") - spawnFileRoutes(file, env, db) + routes.RegisterFileRoutes(file, env, db) r.Static("/assets", "./web/frontend/dist/assets") r.NoRoute(func(c *gin.Context) { diff --git a/internal/api/middleware/middleware.go b/internal/api/middleware/middleware.go index 98f1ff9..da1b91e 100644 --- a/internal/api/middleware/middleware.go +++ b/internal/api/middleware/middleware.go @@ -3,6 +3,8 @@ package middleware import ( "log/slog" "net/http" + "orbits-server/internal/api/response" + "strings" "time" "github.com/gin-gonic/gin" @@ -36,11 +38,23 @@ func SlogMiddleware(logger *slog.Logger) gin.HandlerFunc { func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { - orbitsKey := c.GetHeader("orbits-key") - if len(orbitsKey) == 0 { - c.AbortWithStatus(http.StatusUnauthorized) + authorizationHeader := c.GetHeader("Authorization") + if len(authorizationHeader) == 0 { + c.AbortWithStatusJSON(http.StatusUnauthorized, response.BasicResponse{ + Msg: "Authorization header is required", + }) return } + headerParts := strings.Split(authorizationHeader, " ") + if len(headerParts) != 2 || headerParts[0] != "Bearer" { + c.AbortWithStatusJSON(http.StatusUnauthorized, response.BasicResponse{ + Msg: "Authorization header is invalid", + }) + return + } + + givenKey := headerParts[1] + slog.Info(givenKey) } } diff --git a/internal/api/response/response.go b/internal/api/response/response.go new file mode 100644 index 0000000..31902e8 --- /dev/null +++ b/internal/api/response/response.go @@ -0,0 +1,11 @@ +package response + +const ( + OkMes string = "OK" + IntErrMes string = "An internal error occured, contact your administrator" +) + +type BasicResponse struct { + Msg string `json:"msg"` + Data any `json:"data"` +} diff --git a/internal/api/routes_api.go b/internal/api/routes/api.go similarity index 59% rename from internal/api/routes_api.go rename to internal/api/routes/api.go index 4261efd..e5bafb8 100644 --- a/internal/api/routes_api.go +++ b/internal/api/routes/api.go @@ -1,29 +1,30 @@ -package api +package routes import ( "log/slog" "net/http" + "orbits-server/internal/api/response" "orbits-server/internal/database" "github.com/gin-gonic/gin" "gorm.io/gorm" ) -func spawnApiRoutes(api *gin.RouterGroup /* env runtime.Environment,*/, db *gorm.DB) { +func RegisterApiRoutes(api *gin.RouterGroup /* env runtime.Environment,*/, db *gorm.DB) { // prefix: api // Display the information on what is going on at the moment api.GET("/command", func(c *gin.Context) { state, err := database.GetState(db) if err != nil { slog.Error("unable to determine state", "error", err) - c.JSON(http.StatusInternalServerError, RespObj{ - Msg: ieMes, + c.JSON(http.StatusInternalServerError, response.BasicResponse{ + Msg: response.IntErrMes, }) return } - c.JSON(http.StatusOK, RespObj{ - Msg: okMes, + c.JSON(http.StatusOK, response.BasicResponse{ + Msg: response.OkMes, Data: state, }) }) @@ -37,14 +38,14 @@ func spawnApiRoutes(api *gin.RouterGroup /* env runtime.Environment,*/, db *gorm files, err := database.GetFiles(db) if err != nil { slog.Error("failed to retrieve available files", "error", err) - c.JSON(http.StatusInternalServerError, RespObj{ - Msg: ieMes, + c.JSON(http.StatusInternalServerError, response.BasicResponse{ + Msg: response.IntErrMes, }) return } - c.JSON(http.StatusOK, RespObj{ - Msg: okMes, + c.JSON(http.StatusOK, response.BasicResponse{ + Msg: response.OkMes, Data: files, }) }) diff --git a/internal/api/routes_file.go b/internal/api/routes/file.go similarity index 73% rename from internal/api/routes_file.go rename to internal/api/routes/file.go index 202b22b..5468459 100644 --- a/internal/api/routes_file.go +++ b/internal/api/routes/file.go @@ -1,9 +1,10 @@ -package api +package routes import ( "errors" "log/slog" "net/http" + "orbits-server/internal/api/response" "orbits-server/internal/database" "orbits-server/internal/utility" "path/filepath" @@ -12,7 +13,7 @@ import ( "gorm.io/gorm" ) -func spawnFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB) { +func RegisterFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB) { // /file/ file.GET("/:filename", func(c *gin.Context) { f := c.Param("filename") @@ -27,7 +28,7 @@ func spawnFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB f, err := c.FormFile("file") if err != nil { slog.Debug("no file or file headers provided on the request", "error", err) - c.JSON(http.StatusBadRequest, RespObj{ + c.JSON(http.StatusBadRequest, response.BasicResponse{ Msg: "a file is required", }) return @@ -42,8 +43,8 @@ func spawnFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB fileData, err := database.BuildFileRecord(readerStream, f.Filename, env.ContentDirectory) if err != nil { slog.Error("failed to enroll file to the database", "error", err) - c.JSON(http.StatusInternalServerError, RespObj{ - Msg: ieMes, + c.JSON(http.StatusInternalServerError, response.BasicResponse{ + Msg: response.IntErrMes, }) return } @@ -51,13 +52,13 @@ func spawnFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB if err := database.RegisterFile(db, fileData); err != nil { if errors.Is(err, gorm.ErrDuplicatedKey) { slog.Debug("discarding file since its checksum is a duplicate", "error", err) - c.JSON(http.StatusConflict, RespObj{ + c.JSON(http.StatusConflict, response.BasicResponse{ Msg: "file checksum already exists", }) } else { slog.Error("failed to insert filedata to the database", "error", err) - c.JSON(http.StatusInternalServerError, RespObj{ - Msg: ieMes, + c.JSON(http.StatusInternalServerError, response.BasicResponse{ + Msg: response.IntErrMes, }) } return @@ -66,14 +67,14 @@ func spawnFileRoutes(file *gin.RouterGroup, env utility.Environment, db *gorm.DB // save to filesystem after everything has given a green light if err := c.SaveUploadedFile(f, fileData.FilePath); err != nil { slog.Error("failed to receive the file over http:", "error", err) - c.JSON(http.StatusInternalServerError, RespObj{ - Msg: ieMes, + c.JSON(http.StatusInternalServerError, response.BasicResponse{ + Msg: response.IntErrMes, }) return } slog.Info("saved file to local filesystem and database") - c.JSON(http.StatusCreated, RespObj{ + c.JSON(http.StatusCreated, response.BasicResponse{ Msg: "file has succesfully been uploaded", Data: fileData, }) diff --git a/internal/database/define.go b/internal/database/define.go index db85623..067680a 100644 --- a/internal/database/define.go +++ b/internal/database/define.go @@ -36,15 +36,13 @@ type Command struct { Timestamps } -type Key struct { +type AccessKey struct { ID int `gorm:"primaryKey;not null;"` MetaName string KeyName string `gorm:"not null;"` // We don't store the key itself, we hash the key KeyHash string `gorm:"not null;"` // we're cooking without pepper - KeySalt string `gorm:"not null;"` - CreatedAt time.Time `gorm:"not null;"` Timestamps }