aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorDoog <157747121+doogongithub@users.noreply.github.com>2024-02-29 20:13:48 -0500
committerDoog <157747121+doogongithub@users.noreply.github.com>2024-02-29 20:13:48 -0500
commit9f9a33cbf55d38987a66b709284d2bb4ffea0fe9 (patch)
tree1e0539e708983ca05bb4e07d22b9ec10b95d2473 /api
parente37c73e33a4aaf7fb8d25b5af03627f20bcda19f (diff)
modify api, build additional FE components, add types
Diffstat (limited to 'api')
-rw-r--r--api/go.mod3
-rw-r--r--api/go.sum2
-rw-r--r--api/lib/models.go38
-rw-r--r--api/main.go48
4 files changed, 62 insertions, 29 deletions
diff --git a/api/go.mod b/api/go.mod
index 08ad9e1..6a326bc 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -4,7 +4,9 @@ go 1.18
4 4
5require ( 5require (
6 github.com/gin-gonic/gin v1.9.1 6 github.com/gin-gonic/gin v1.9.1
7 github.com/google/uuid v1.6.0
7 github.com/mattn/go-sqlite3 v1.14.22 8 github.com/mattn/go-sqlite3 v1.14.22
9 golang.org/x/crypto v0.19.0
8) 10)
9 11
10require ( 12require (
@@ -27,7 +29,6 @@ require (
27 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 29 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
28 github.com/ugorji/go/codec v1.2.12 // indirect 30 github.com/ugorji/go/codec v1.2.12 // indirect
29 golang.org/x/arch v0.7.0 // indirect 31 golang.org/x/arch v0.7.0 // indirect
30 golang.org/x/crypto v0.19.0 // indirect
31 golang.org/x/net v0.21.0 // indirect 32 golang.org/x/net v0.21.0 // indirect
32 golang.org/x/sys v0.17.0 // indirect 33 golang.org/x/sys v0.17.0 // indirect
33 golang.org/x/text v0.14.0 // indirect 34 golang.org/x/text v0.14.0 // indirect
diff --git a/api/go.sum b/api/go.sum
index 5174feb..115a832 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -29,6 +29,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
29github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 29github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
30github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 30github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
31github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 31github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
32github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
33github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
32github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 34github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
33github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 35github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
34github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 36github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
diff --git a/api/lib/models.go b/api/lib/models.go
index 92e5703..f959519 100644
--- a/api/lib/models.go
+++ b/api/lib/models.go
@@ -1,23 +1,41 @@
1package models 1package models
2 2
3import "time" 3import (
4 "time"
5 "github.com/google/uuid"
6)
4 7
5type Statistic struct { 8type Statistic struct {
6 ID int64 `json:"id"` 9 ID int64 `json:"-"`
7 Date time.Time `json:"date"` 10 Date time.Time `json:"date"`
8 UserID int64 `json:"user_id"` 11 User User `json:"user"`
9 Quantity int `json:"quantity"` 12 Quantity int `json:"quantity"`
10} 13}
11 14
12type User struct { 15type User struct {
13 ID int64 16 ID int64 `json:"-"`
14 Name string 17 Name string `json:"name"`
18 UUID uuid.UUID `json:"uuid"`
19 Password string `json:"-"`
15} 20}
16 21
17type Token struct { 22type Token struct {
18 ID int64 23 ID int64 `json:"-"`
19 UserID int64 24 UserID int64 `json:"user_id"`
20 Token string 25 Token string `json:"token"`
21 CreatedAt time.Time 26 CreatedAt time.Time `json:"created_at"`
22 ExpiredAt time.Time 27 ExpiredAt time.Time `json:"expired_at"`
28}
29
30type Preference struct {
31 ID int64 `json:"-"`
32 Color string `json:"color"`
33 UserID int64 `json:"-"`
34 Size Size `json:"size"`
35}
36
37type Size struct {
38 ID int64 `json:"-"`
39 Size int64 `json:"size"`
40 Unit string `json:"unit"`
23} 41}
diff --git a/api/main.go b/api/main.go
index 292a5f9..91b7929 100644
--- a/api/main.go
+++ b/api/main.go
@@ -10,6 +10,7 @@ import (
10 10
11 "github.com/gin-gonic/gin" 11 "github.com/gin-gonic/gin"
12 _ "github.com/mattn/go-sqlite3" 12 _ "github.com/mattn/go-sqlite3"
13 "golang.org/x/crypto/bcrypt"
13 "water/api/lib" 14 "water/api/lib"
14) 15)
15 16
@@ -29,6 +30,7 @@ func CORSMiddleware() gin.HandlerFunc {
29 } 30 }
30} 31}
31 32
33// generatToken will g
32func generateToken() string { 34func generateToken() string {
33 token := make([]byte, 32) 35 token := make([]byte, 32)
34 rand.Read(token) 36 rand.Read(token)
@@ -43,6 +45,7 @@ func establishDBConnection() *sql.DB {
43 return db 45 return db
44} 46}
45 47
48
46func checkForTokenInContext(c *gin.Context) (string, error) { 49func checkForTokenInContext(c *gin.Context) (string, error) {
47 authorizationHeader := c.GetHeader("Authorization") 50 authorizationHeader := c.GetHeader("Authorization")
48 if authorizationHeader == "" { 51 if authorizationHeader == "" {
@@ -54,6 +57,7 @@ func checkForTokenInContext(c *gin.Context) (string, error) {
54 if len(parts) != 2 || parts[0] != "Bearer" { 57 if len(parts) != 2 || parts[0] != "Bearer" {
55 return "", errors.New("Invalid Authorization header format") 58 return "", errors.New("Invalid Authorization header format")
56 } 59 }
60
57 61
58 return parts[1], nil 62 return parts[1], nil
59} 63}
@@ -73,15 +77,6 @@ func TokenRequired() gin.HandlerFunc {
73 } 77 }
74} 78}
75 79
76type User struct {
77 Username string
78 Password string
79}
80
81var users = map[string]User{
82 "user1": {"user1", "password1"},
83}
84
85func setupRouter() *gin.Engine { 80func setupRouter() *gin.Engine {
86 // Disable Console Color 81 // Disable Console Color
87 // gin.DisableConsoleColor() 82 // gin.DisableConsoleColor()
@@ -100,16 +95,31 @@ func setupRouter() *gin.Engine {
100 return 95 return
101 } 96 }
102 97
103 user, exists := users[username] 98 db := establishDBConnection()
99 defer db.Close()
100
101 var user models.User
102 var preference models.Preference
103 var size models.Size
104
105 row := db.QueryRow("SELECT name, uuid, password, color, size, unit FROM Users u INNER JOIN Preferences p ON p.user_id = u.id INNER JOIN Sizes s ON p.size_id = s.id WHERE u.name = ?", username)
106 if err := row.Scan(&user.Name, &user.UUID, &user.Password, &preference.Color, &size.Size, &size.Unit); err != nil {
107 if err == sql.ErrNoRows {
108 c.AbortWithStatus(http.StatusUnauthorized)
109 return
110 }
111 }
112
113 if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
114 c.AbortWithStatus(http.StatusUnauthorized)
115 return
116 }
104 117
105 if !exists || user.Password != password { 118 preference.Size = size
106 c.AbortWithStatus(http.StatusUnauthorized)
107 return
108 }
109 119
110 // Generate a simple API token 120 // Generate a simple API token
111 apiToken := generateToken() 121 apiToken := generateToken()
112 c.JSON(http.StatusOK, gin.H{"token": apiToken}) 122 c.JSON(http.StatusOK, gin.H{"token": apiToken, "user": user, "preferences": preference})
113 }) 123 })
114 124
115 stats := api.Group("stats") 125 stats := api.Group("stats")
@@ -119,7 +129,7 @@ func setupRouter() *gin.Engine {
119 db := establishDBConnection() 129 db := establishDBConnection()
120 defer db.Close() 130 defer db.Close()
121 131
122 rows, err := db.Query("SELECT * FROM statistics"); 132 rows, err := db.Query("SELECT s.date, s.quantity, u.uuid, u.name FROM Statistics s INNER JOIN Users u ON u.id = s.user_id");
123 if err != nil { 133 if err != nil {
124 c.JSON(500, gin.H{"error": err.Error()}) 134 c.JSON(500, gin.H{"error": err.Error()})
125 return 135 return
@@ -129,10 +139,12 @@ func setupRouter() *gin.Engine {
129 var data []models.Statistic 139 var data []models.Statistic
130 for rows.Next() { 140 for rows.Next() {
131 var stat models.Statistic 141 var stat models.Statistic
132 if err := rows.Scan(&stat.ID, &stat.Date, &stat.UserID, &stat.Quantity); err != nil { 142 var user models.User
143 if err := rows.Scan(&stat.Date, &stat.Quantity, &user.UUID, &user.Name); err != nil {
133 c.JSON(500, gin.H{"error": err.Error()}) 144 c.JSON(500, gin.H{"error": err.Error()})
134 return 145 return
135 } 146 }
147 stat.User = user
136 data = append(data, stat) 148 data = append(data, stat)
137 } 149 }
138 150
@@ -150,7 +162,7 @@ func setupRouter() *gin.Engine {
150 db := establishDBConnection() 162 db := establishDBConnection()
151 defer db.Close() 163 defer db.Close()
152 164
153 result, err := db.Exec("INSERT INTO statistics (date, user_id, quantity) values (?, ?, ?)", stat.Date, stat.UserID, stat.Quantity) 165 result, err := db.Exec("INSERT INTO statistics (date, user_id, quantity) values (?, ?, ?)", stat.Date, 1, stat.Quantity)
154 166
155 if err != nil { 167 if err != nil {
156 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 168 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})