From aa0dfcbe67f70dd8fb3c7e68b4a9db4616e70f6a Mon Sep 17 00:00:00 2001 From: Maxim <74974283+maximka76667@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:48:07 +0100 Subject: [PATCH] feat: disable env variables and add list endpoint --- main.go | 32 ++++++++++++-------------- pkg/api/handlers.go | 29 ++++++++++++++++------- pkg/api/router.go | 4 ++-- pkg/store/store.go | 56 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 84 insertions(+), 37 deletions(-) diff --git a/main.go b/main.go index 8a5608f..60871a4 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,6 @@ package main import ( "log" - "os" - "strconv" "github.com/Hyperloop-UPV/cloud-logs/pkg/api" "github.com/Hyperloop-UPV/cloud-logs/pkg/store" @@ -19,22 +17,22 @@ func main() { // Load configuration from environment variables _ = godotenv.Load() - passwordHash := os.Getenv("AUTH_PASSWORD_HASH") - if passwordHash == "" { - log.Fatal("AUTH_PASSWORD_HASH is required") - } - jwtSecret := os.Getenv("JWT_SECRET") - if jwtSecret == "" { - log.Fatal("JWT_SECRET is required") - } - v := os.Getenv("JWT_TTL_SECONDS") - jwtTTLSeconds, err := strconv.ParseInt(v, 10, 64) - if err != nil { - log.Fatal("JWT_TTL_SECONDS is required") - } + // passwordHash := os.Getenv("AUTH_PASSWORD_HASH") + // if passwordHash == "" { + // log.Fatal("AUTH_PASSWORD_HASH is required") + // } + // jwtSecret := os.Getenv("JWT_SECRET") + // if jwtSecret == "" { + // log.Fatal("JWT_SECRET is required") + // } + // v := os.Getenv("JWT_TTL_SECONDS") + // jwtTTLSeconds, err := strconv.ParseInt(v, 10, 64) + // if err != nil { + // log.Fatal("JWT_TTL_SECONDS is required") + // } - r := api.NewRouter(db, passwordHash, jwtSecret, jwtTTLSeconds) + r := api.NewRouter(db, "password", "secret", 20) if err := r.Run(":8080"); err != nil { log.Fatal(err) } -} \ No newline at end of file +} diff --git a/pkg/api/handlers.go b/pkg/api/handlers.go index 6497ba8..b0ff011 100644 --- a/pkg/api/handlers.go +++ b/pkg/api/handlers.go @@ -12,8 +12,8 @@ import ( "github.com/gin-gonic/gin" ) -type Handler struct{ - db *sql.DB +type Handler struct { + db *sql.DB passwordHash string jwtSecret string @@ -26,10 +26,10 @@ type LoginRequest struct { func NewHandler(db *sql.DB, passwordHash string, jwtSecret string, jwtTTL time.Duration) *Handler { return &Handler{ - db: db, + db: db, passwordHash: passwordHash, - jwtSecret: jwtSecret, - jwtTTL: jwtTTL, + jwtSecret: jwtSecret, + jwtTTL: jwtTTL, } } @@ -44,7 +44,6 @@ func (h *Handler) Login(c *gin.Context) { return } - //fmt.Printf("login input received: %s\n", req.Password) if !auth.CheckPasswordHash(req.Password, h.passwordHash) { @@ -69,6 +68,19 @@ func (h *Handler) Login(c *gin.Context) { }) } +func (h *Handler) ListUploadedArchives(c *gin.Context) { + archives, err := store.ListUploadedArchives(h.db) + + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "failed to list uploaded archives", + }) + return + } + + c.JSON(http.StatusOK, archives) +} + func (h *Handler) UploadArchive(c *gin.Context) { fileHeader, err := c.FormFile("file") if err != nil { @@ -101,7 +113,7 @@ func (h *Handler) UploadArchive(c *gin.Context) { contentType = "application/octet-stream" } - err = store.UploadArchive(h.db, fileHeader.Filename, contentType, fileHeader.Size, fileData) + id, err := store.UploadArchive(h.db, fileHeader.Filename, contentType, fileHeader.Size, fileData) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "failed to save uploaded archive", @@ -114,6 +126,7 @@ func (h *Handler) UploadArchive(c *gin.Context) { "filename": fileHeader.Filename, "size_bytes": fileHeader.Size, "content_type": contentType, + "file_id": id, }) } @@ -147,4 +160,4 @@ func (h *Handler) DownloadLogsArchive(c *gin.Context) { c.Header("Content-Type", archive.ContentType) c.Header("Content-Disposition", `attachment; filename="`+archive.Filename+`"`) c.Data(http.StatusOK, archive.ContentType, archive.FileData) -} \ No newline at end of file +} diff --git a/pkg/api/router.go b/pkg/api/router.go index 96e008e..8039860 100644 --- a/pkg/api/router.go +++ b/pkg/api/router.go @@ -16,9 +16,9 @@ func NewRouter(db *sql.DB, passwordHash string, jwtSecret string, jwtTTL int64) logs := r.Group("/logs") // TDO: uncomment when logs saving and loading is implemented //logs.Use(AuthMiddleware(jwtSecret)) + logs.GET("/", h.ListUploadedArchives) logs.GET("/download/:id", h.DownloadLogsArchive) logs.POST("/upload", h.UploadArchive) - return r -} \ No newline at end of file +} diff --git a/pkg/store/store.go b/pkg/store/store.go index a5f84d4..f6fc45c 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -9,11 +9,11 @@ import ( ) type UploadedArchive struct { - ID int64 - Filename string - ContentType string - SizeBytes int64 - FileData []byte + ID int64 `json:"id"` + Filename string `json:"filename"` + ContentType string `json:"content_type"` + SizeBytes int64 `json:"size_bytes"` + FileData []byte `json:"-"` } func InitDb() (*sql.DB, error) { @@ -60,15 +60,51 @@ func InitSchema(db *sql.DB) error { return nil } -func UploadArchive(db *sql.DB, filename, contentType string, sizeBytes int64, fileData []byte) error { - _, err := db.Exec(` +func ListUploadedArchives(db *sql.DB) ([]UploadedArchive, error) { + rows, err := db.Query(` + SELECT id, filename, content_type, size_bytes + FROM uploaded_archives + `) + if err != nil { + return nil, fmt.Errorf("failed to list uploaded archives: %w", err) + } + + archives := []UploadedArchive{} + + for rows.Next() { + var archive UploadedArchive + + err := rows.Scan(&archive.ID, &archive.Filename, &archive.ContentType, &archive.SizeBytes) + + if err != nil { + return nil, fmt.Errorf("failed to scan uploaded archive: %w", err) + } + + archives = append(archives, archive) + } + rows.Close() + + return archives, nil +} + +func UploadArchive(db *sql.DB, filename, contentType string, sizeBytes int64, fileData []byte) (int64, error) { + result, err := db.Exec(` INSERT INTO uploaded_archives(filename, content_type, size_bytes, file_data) VALUES(?, ?, ?, ?) `, filename, contentType, sizeBytes, fileData) + if err != nil { - return fmt.Errorf("save uploaded archive: %w", err) + // Return id 0 as invalid db index + return 0, fmt.Errorf("failed to save archive %s to database: %w", filename, err) } - return nil + + id, err := result.LastInsertId() + if err != nil { + // Return id 0 as invalid db index + return 0, fmt.Errorf("error getting last insert id: %w", err) + } + + return id, nil } func GetArchiveByID(db *sql.DB, id int64) (*UploadedArchive, error) { @@ -90,4 +126,4 @@ func GetArchiveByID(db *sql.DB, id int64) (*UploadedArchive, error) { } return &archive, nil -} \ No newline at end of file +}