aboutsummaryrefslogtreecommitdiff
path: root/api/internal/controllers/auth.go
diff options
context:
space:
mode:
authorZach Berwaldt <zberwaldt@tutamail.com>2024-03-07 19:16:07 -0500
committerZach Berwaldt <zberwaldt@tutamail.com>2024-03-07 19:16:07 -0500
commit6651daca670664f3de8af9c7bcb74b1e7c6c6be9 (patch)
treef1bb35ef8b0e1d498842a17b84c87c6ee996274e /api/internal/controllers/auth.go
parent5fa57845052655883120ba4d19a85d8756fb8d8c (diff)
Add CORS middleware and authentication middleware to the API server.
The `setupRouter` function in `main.go` now includes a CORS middleware and a token authentication middleware. The CORS middleware allows cross-origin resource sharing by setting the appropriate response headers. The token authentication middleware checks for the presence of an `Authorization` header with a valid bearer token. If the token is missing or invalid, an unauthorized response is returned. In addition to these changes, a new test file `main_test.go` has been added to test the `/api/v1/auth` route. This test suite includes two test cases: one for successful authentication and one for failed authentication. Update go.mod to include new dependencies. The `go.mod` file has been modified to include two new dependencies: `github.com/spf13/viper` and `github.com/stretchr/testify`. Ignore go.sum changes. Ignore changes in the `go.sum` file, as they only include updates to existing dependencies.
Diffstat (limited to 'api/internal/controllers/auth.go')
-rw-r--r--api/internal/controllers/auth.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/api/internal/controllers/auth.go b/api/internal/controllers/auth.go
new file mode 100644
index 0000000..744a884
--- /dev/null
+++ b/api/internal/controllers/auth.go
@@ -0,0 +1,66 @@
1package controllers
2
3import (
4 "encoding/base64"
5 "net/http"
6 "github.com/gin-gonic/gin"
7 "water/api/database"
8 "errors"
9 "crypto/rand"
10 "database/sql"
11
12 "water/api/models"
13 _ "github.com/mattn/go-sqlite3"
14 "golang.org/x/crypto/bcrypt"
15)
16
17func AuthHandler (c *gin.Context) {
18 username, password, ok := c.Request.BasicAuth()
19 if !ok {
20 c.Header("WWW-Authenticate", `Basic realm="Please enter your username and password."`)
21 c.AbortWithStatus(http.StatusUnauthorized)
22 return
23 }
24
25 db := database.EstablishDBConnection()
26 defer func(db *sql.DB) {
27 err := db.Close()
28 if err != nil {
29 c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
30 return
31 }
32 }(db)
33
34 var user models.User
35 var preference models.Preference
36 var size models.Size
37
38 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)
39 if err := row.Scan(&user.Name, &user.UUID, &user.Password, &preference.Color, &size.Size, &size.Unit); err != nil {
40 if errors.Is(err, sql.ErrNoRows) {
41 c.AbortWithStatus(http.StatusUnauthorized)
42 return
43 }
44 }
45
46 if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
47 c.AbortWithStatus(http.StatusUnauthorized)
48 return
49 }
50
51 preference.Size = size
52
53 // Generate a simple API token
54 apiToken := generateToken()
55 c.JSON(http.StatusOK, gin.H{"token": apiToken, "user": user, "preferences": preference})
56}
57
58// generatToken will g
59func generateToken() string {
60 token := make([]byte, 32)
61 _, err := rand.Read(token)
62 if err != nil {
63 return ""
64 }
65 return base64.StdEncoding.EncodeToString(token)
66} \ No newline at end of file