-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.go
134 lines (110 loc) · 4.11 KB
/
handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package handlers
import (
"fmt"
"log"
"net/http"
"time"
"github.com/amin-abbasi/go-boilerplate/configs"
"github.com/amin-abbasi/go-boilerplate/models"
srv "github.com/amin-abbasi/go-boilerplate/services"
"github.com/dgrijalva/jwt-go"
"github.com/labstack/echo/v4"
)
func Ping(ctx echo.Context) error {
return ctx.String(http.StatusOK, "pong")
}
var (
adminUsername = configs.GetEnvVariable("ADMIN_USER")
adminPassword = configs.GetEnvVariable("ADMIN_PASS")
secretKeyBytes = []byte(configs.GetEnvVariable("JWT_SECRET_KEY"))
)
type AdminLoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
func LoginAdmin(ctx echo.Context) error {
// Bind the request body to the AdminLoginRequest struct
req := new(AdminLoginRequest)
if err := ctx.Bind(req); err != nil {
// return srv.SendResponse(ctx, http.StatusBadRequest, map[string]string{"error": "Invalid request body"})
return srv.SendResponse(ctx, 400, "Invalid request body")
}
// Validate credentials (this is a simple example, use your authentication logic here)
if req.Username == adminUsername && req.Password == adminPassword {
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["username"] = adminUsername
exp := time.Now().Add(time.Hour * 1).Unix() // Token expiration time
claims["exp"] = exp
tokenString, err := token.SignedString(secretKeyBytes)
if err != nil {
log.Println(">>>> Error Generating Token: ", err)
return srv.SendResponse(ctx, 500, "Error Generating Token", err)
}
// Save Token in Redis
expTime := time.Unix(exp, 0)
durationUntilExp := time.Until(expTime)
srv.SetToken(tokenString, durationUntilExp)
return srv.SendResponse(ctx, 200, "success", map[string]interface{}{"token": tokenString})
}
return srv.SendResponse(ctx, 401, "invalid credentials")
}
func Login(ctx echo.Context) error {
var user models.User
if err := ctx.Bind(&user); err != nil {
return srv.SendResponse(ctx, 400, "body validation error", err)
}
// Get user from DB
storedUser, err := models.GetByUsername(ctx.Request().Context(), user.UserName)
if err != nil {
log.Println(">>>> User not found: ", err)
return srv.SendResponse(ctx, 401, "User not found.")
}
// Validate credentials (this is a simple example, use your authentication logic here)
if storedUser.Password != user.Password {
return srv.SendResponse(ctx, 401, "Invalid Credentials.")
}
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["username"] = user.UserName
exp := time.Now().Add(time.Hour * 1).Unix() // Token expiration time
claims["exp"] = exp
tokenString, err := token.SignedString(secretKeyBytes)
if err != nil {
log.Println(">>>> Error on generating token: ", err)
return srv.SendResponse(ctx, 500, "Error on generating token.", err)
}
// Save Token in Redis
expTime := time.Unix(exp, 0)
durationUntilExp := time.Until(expTime)
srv.SetToken(tokenString, durationUntilExp)
return srv.SendResponse(ctx, 200, "success", map[string]interface{}{"token": tokenString})
}
func GetUser(ctx echo.Context) error {
username := ctx.Param("name")
user, err := models.GetByUsername(ctx.Request().Context(), username)
if err != nil {
return srv.SendResponse(ctx, 401, "User not found.")
}
return srv.SendResponse(ctx, 200, "success", map[string]interface{}{"user": user})
}
func CreateUser(ctx echo.Context) error {
var user models.User
if err := ctx.Bind(&user); err != nil {
return srv.SendResponse(ctx, 400, "Body Validation Error", err)
}
// Check if the username already exists in the db
exists, _ := models.GetByUsername(ctx.Request().Context(), user.UserName)
if exists != nil {
return srv.SendResponse(ctx, 409, "Username already exists.")
}
// adds user in db
newUser, err := models.User.Create(user, ctx.Request().Context())
if err != nil {
// Convert error to string
errString := fmt.Sprintf("%v", err)
log.Println(">>>>>>> Could not create user: ", errString)
return srv.SendResponse(ctx, 401, "Could not create user.", errString)
}
return srv.SendResponse(ctx, 200, "success", map[string]interface{}{"status": "ok", "user": newUser})
}