From e37c73e33a4aaf7fb8d25b5af03627f20bcda19f Mon Sep 17 00:00:00 2001 From: Doog <157747121+doogongithub@users.noreply.github.com> Date: Sat, 24 Feb 2024 20:08:35 -0500 Subject: add gitignore --- api/main.go | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 19 deletions(-) (limited to 'api/main.go') diff --git a/api/main.go b/api/main.go index ebae5d1..292a5f9 100644 --- a/api/main.go +++ b/api/main.go @@ -4,8 +4,13 @@ import ( "net/http" "crypto/rand" "encoding/base64" + "database/sql" + "strings" + "errors" "github.com/gin-gonic/gin" + _ "github.com/mattn/go-sqlite3" + "water/api/lib" ) func CORSMiddleware() gin.HandlerFunc { @@ -30,6 +35,44 @@ func generateToken() string { return base64.StdEncoding.EncodeToString(token) } +func establishDBConnection() *sql.DB { + db, err := sql.Open("sqlite3", "../db/water.sqlite3") + if err != nil { + panic(err) + } + return db +} + +func checkForTokenInContext(c *gin.Context) (string, error) { + authorizationHeader := c.GetHeader("Authorization") + if authorizationHeader == "" { + return "", errors.New("Authorization header is missing") + } + + parts := strings.Split(authorizationHeader, " ") + + if len(parts) != 2 || parts[0] != "Bearer" { + return "", errors.New("Invalid Authorization header format") + } + + return parts[1], nil +} + + +func TokenRequired() gin.HandlerFunc { + return func(c *gin.Context) { + _, err := checkForTokenInContext(c) + + if err != nil { + c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + c.Abort() + return + } + + c.Next() + } +} + type User struct { Username string Password string @@ -44,6 +87,8 @@ func setupRouter() *gin.Engine { // gin.DisableConsoleColor() r := gin.Default() r.Use(CORSMiddleware()) + r.Use(gin.Logger()) + r.Use(gin.Recovery()) api := r.Group("api/v1") @@ -68,26 +113,70 @@ func setupRouter() *gin.Engine { }) stats := api.Group("stats") + stats.Use(TokenRequired()) + { + stats.GET("/", func(c *gin.Context) { + db := establishDBConnection() + defer db.Close() + + rows, err := db.Query("SELECT * FROM statistics"); + if err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + defer rows.Close() + + var data []models.Statistic + for rows.Next() { + var stat models.Statistic + if err := rows.Scan(&stat.ID, &stat.Date, &stat.UserID, &stat.Quantity); err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + data = append(data, stat) + } + + c.JSON(http.StatusOK, data) + }) + + stats.POST("/", func(c *gin.Context) { + var stat models.Statistic + + if err := c.BindJSON(&stat); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + db := establishDBConnection() + defer db.Close() + + result, err := db.Exec("INSERT INTO statistics (date, user_id, quantity) values (?, ?, ?)", stat.Date, stat.UserID, stat.Quantity) + + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + + id, err := result.LastInsertId() + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + + c.JSON(http.StatusCreated, gin.H{"status": "created", "id": id}) + }) + + stats.GET("/:uuid", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"status": "ok", "uuid": c.Param("uuid")}) + }) + + stats.PATCH("/:uuid", func(c *gin.Context) { + c.JSON(http.StatusNoContent, gin.H{"status": "No Content"}) + }) + + stats.DELETE("/:uuid", func(c *gin.Context) { + c.JSON(http.StatusNoContent, gin.H{"status": "No Content"}) + }) + } - stats.GET("/", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"status": "ok"}) - }) - - stats.POST("/", func(c *gin.Context) { - c.JSON(http.StatusCreated, gin.H{"status": "created"}) - }) - - stats.GET("/:uuid", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"status": "ok", "uuid": c.Param("uuid")}) - }) - - stats.PATCH("/:uuid", func(c *gin.Context) { - c.JSON(http.StatusNoContent, gin.H{"status": "No Content"}) - }) - - stats.DELETE("/:uuid", func(c *gin.Context) { - c.JSON(http.StatusNoContent, gin.H{"status": "No Content"}) - }) return r } -- cgit v1.1