feat: add basic workings

This commit is contained in:
2026-04-29 23:38:43 +02:00
parent da3dee9ae7
commit 76c893ae7e
14 changed files with 167 additions and 112 deletions
+11 -11
View File
@@ -12,7 +12,7 @@ const (
CreationMes string = "Object successfully created"
DeletionMes string = "Object successfully deleted"
NotFoundMes string = "Requested object not found"
BadRequestMes string = "Request did not satisfy requirements"
BadRequestMes string = "Request did not satisfy requirements (bad request)"
ConflictMes string = "Duplicate object"
IntErrMes string = "An internal error occured, contact your administrator"
)
@@ -24,20 +24,20 @@ type ResponseObject struct {
// we swap out the hash for the keycontent
type KeyResponse struct {
ID int `json:"id"`
MetaName string `json:"metaName"`
KeyName string `json:"keyName"`
KeyContent string `json:"keyContent"`
Revoked bool `json:"revoked"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ExpiresAt time.Time `json:"expiresAt"`
ID int `json:"ID"`
MetaName string `json:"metaName"`
KeyID string `json:"keyID"`
KeySecret string `json:"keySecret"`
Revoked bool `json:"revoked"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ExpiresAt time.Time `json:"expiresAt"`
}
type FileResponse struct {
ID int `json:"id"`
ID int `json:"ID"`
MetaName string `json:"metaName"`
FileName string `json:"fileName"`
FileID string `json:"fileID"`
FilePath string `json:"filePath"`
Checksum string `json:"checksum"`
MediaType string `json:"mediaType"`
+14 -23
View File
@@ -5,7 +5,6 @@ import (
"net/http"
"orbits-server/internal/server/api/assets"
"orbits-server/internal/server/service"
"orbits-server/internal/shared/security"
"strings"
"time"
@@ -13,6 +12,8 @@ import (
"gorm.io/gorm"
)
const authPrefix = "Bearer"
func SlogMiddleware(logger *slog.Logger) gin.HandlerFunc {
// Make a slog-looking logger, inspired by the gin docs themself
// JSON logger: https://gin-gonic.com/en/docs/logging/structured-logging/
@@ -45,40 +46,30 @@ func AuthMiddleware(db *gorm.DB) gin.HandlerFunc {
keyService := service.NewKeyService(db)
return func(c *gin.Context) {
authorizationHeader := c.GetHeader("Authorization")
if len(authorizationHeader) == 0 {
header := c.GetHeader("Authorization")
if len(header) == 0 {
c.AbortWithStatusJSON(http.StatusUnauthorized, assets.ResponseObject{
Msg: "Authorization header is required",
})
return
}
headerParts := strings.Split(authorizationHeader, " ")
// The header must be a specific format, 0 being the bearer text and 1 being the token itself, making it 2 pieces total
// In the following if statement we verify both parts if the part after Bearer is empty its only 1 part for example
if len(headerParts) != 2 || headerParts[0] != "Bearer" {
if !strings.HasPrefix(header, authPrefix) {
c.AbortWithStatusJSON(http.StatusUnauthorized, assets.ResponseObject{
Msg: "Authorization header is invalid",
Msg: "Invalid authorization header",
})
return
}
candidateKey := headerParts[1]
storedKeys, err := keyService.ListValidKeyHashes()
if err != nil {
slog.Error("failed to retrieve key hashes", "error", err)
assets.InternalErrorResponse(c)
token := strings.TrimSpace(header[len(authPrefix):])
ok := keyService.Validate(token)
if !ok {
c.AbortWithStatusJSON(http.StatusUnauthorized, assets.ResponseObject{
Msg: "Invalid key",
})
return
}
for _, key := range storedKeys {
if match := security.CompareKey(key, candidateKey); match {
c.Next()
return
}
}
c.AbortWithStatusJSON(http.StatusUnauthorized, assets.ResponseObject{
Msg: "invalid key",
})
c.Next()
}
}
+5 -5
View File
@@ -18,8 +18,8 @@ func RegisterFileRoutes(file *gin.RouterGroup, env bootstrap.Environment, db *go
// for example: /file/<file-name>
// file download route / display contents
file.GET("/:fileName", func(c *gin.Context) {
fileParam := c.Param("fileName")
file.GET("/:fileID", func(c *gin.Context) {
fileParam := c.Param("fileID")
fp := filepath.Join(env.ContentDirectory, fileParam)
assets.FileDownloadResponse(c, fp)
@@ -72,8 +72,8 @@ func RegisterFileRoutes(file *gin.RouterGroup, env bootstrap.Environment, db *go
})
// delete route
file.DELETE("/:filename", func(c *gin.Context) {
fileParam := c.Param("filename")
file.DELETE("/:fileID", func(c *gin.Context) {
fileParam := c.Param("fileID")
if err := fileService.DeleteByName(fileParam); err != nil {
slog.Error("file not found", "error", err)
@@ -81,7 +81,7 @@ func RegisterFileRoutes(file *gin.RouterGroup, env bootstrap.Environment, db *go
return
}
slog.Info("received a delete request for a file", "fileName", fileParam)
slog.Info("received a delete request for a file", "fileID", fileParam)
assets.DeletionResponse(c)
})
+3 -3
View File
@@ -28,13 +28,12 @@ func RegisterKeyRoutes(api *gin.RouterGroup, db *gorm.DB) {
keyResponse, err := keyService.Create(body.Name, body.ExpiresAt)
if err != nil {
slog.Error("failed to create key", "error", err)
assets.InternalErrorResponse(c)
slog.Error("failed to build key record", "error", err)
assets.BadRequestResponse(c)
return
}
slog.Info("saved key to database")
assets.CreationResponse(c, keyResponse)
})
@@ -44,6 +43,7 @@ func RegisterKeyRoutes(api *gin.RouterGroup, db *gorm.DB) {
if err := keyService.DeleteByName(keyParam); err != nil {
slog.Error("key not found", "error", err)
assets.NotFoundResponse(c)
return
}
slog.Info("received a delete request for a key", "keyName", keyParam)