Passed
Pull Request — main (#17)
by Yume
01:15
created

controllers.AuthDebugMode   A

Complexity

Conditions 2

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nop 1
dl 0
loc 16
rs 9.8
c 0
b 0
f 0
1
package controllers
2
3
import (
4
	"memnixrest/app/models"
5
	"memnixrest/app/queries"
6
	"memnixrest/pkg/database"
7
	"memnixrest/pkg/utils"
8
	"net/http"
9
	"os"
10
	"strconv"
11
	"strings"
12
	"time"
13
14
	"github.com/gofiber/fiber/v2"
15
	"github.com/golang-jwt/jwt"
16
	"golang.org/x/crypto/bcrypt"
17
)
18
19
var SecretKey = os.Getenv("SECRET")
20
21
func Register(c *fiber.Ctx) error {
22
	var data map[string]string
23
	db := database.DBConn // DB Conn
24
25
	if err := c.BodyParser(&data); err != nil {
26
		return err
27
	}
28
29
	password, _ := bcrypt.GenerateFromPassword([]byte(data["password"]), 14)
30
	user := models.User{
31
		Username: data["username"],
32
		Email:    strings.ToLower(data["email"]),
33
		Password: password,
34
	}
35
36
	if err := db.Create(&user).Error; err != nil {
37
		return queries.RequestError(c, http.StatusForbidden, utils.ErrorAlreadyUsedEmail)
38
	}
39
40
	log := queries.CreateLog(models.LogUserRegister, "Register: "+user.Username)
41
	_ = queries.CreateUserLog(user.ID, log)
42
43
	return c.JSON(user)
44
}
45
46
func Login(c *fiber.Ctx) error {
47
	var data map[string]string
48
	db := database.DBConn // DB Conn
49
50
	if err := c.BodyParser(&data); err != nil {
51
		return err
52
	}
53
54
	var user models.User
55
56
	db.Where("email = ?", strings.ToLower(data["email"])).First(&user)
57
58
	// handle error
59
	if user.ID == 0 { //default Id when return nil
60
		c.Status(fiber.StatusNotFound)
61
		return c.JSON(fiber.Map{
62
			"message": "User not found!",
63
		})
64
	}
65
66
	// match password
67
	if err := bcrypt.CompareHashAndPassword(user.Password, []byte(data["password"])); err != nil {
68
		c.Status(fiber.StatusBadRequest)
69
		return c.JSON(fiber.Map{
70
			"message": "incorrect password!",
71
		})
72
	}
73
74
	claims := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{
75
		Issuer:    strconv.Itoa(int(user.ID)),
76
		ExpiresAt: time.Now().Add(time.Hour * 168).Unix(), //7 day
77
	})
78
79
	token, err := claims.SignedString([]byte(SecretKey))
80
	if err != nil {
81
		c.Status(fiber.StatusInternalServerError)
82
		return c.JSON(fiber.Map{
83
			"message": "error when logging in !",
84
		})
85
	}
86
87
	cookie := fiber.Cookie{
88
		Name:     "memnix-jwt",
89
		Value:    token,
90
		Expires:  time.Now().Add(time.Hour * 168),
91
		HTTPOnly: true,
92
		SameSite: "none",
93
		Secure:   true,
94
	}
95
	c.Cookie(&cookie)
96
97
	log := queries.CreateLog(models.LogUserLogin, "Login: "+user.Username)
98
	_ = queries.CreateUserLog(user.ID, log)
99
100
	return c.JSON(fiber.Map{
101
		"message": "Login Succeeded",
102
		//"token": token,
103
	})
104
}
105
106
func User(c *fiber.Ctx) error {
107
	cookie := c.Cookies("memnix-jwt")
108
	db := database.DBConn // DB Conn
109
110
	token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
111
		return []byte(SecretKey), nil
112
	})
113
114
	if err != nil {
115
		c.Status(fiber.StatusUnauthorized)
116
		return c.JSON(fiber.Map{
117
			"message": "Unauthenticated",
118
		})
119
	}
120
121
	claims := token.Claims.(*jwt.StandardClaims)
122
123
	var user models.User
124
125
	db.Where("id = ?", claims.Issuer).First(&user)
126
127
	return c.JSON(user)
128
}
129
130
func AuthDebugMode(c *fiber.Ctx) models.ResponseAuth {
131
	db := database.DBConn // DB Conn
132
	var user models.User
133
134
	if res := db.Where("id = ?", 6).First(&user); res.Error != nil {
135
		c.Status(fiber.StatusInternalServerError)
136
		return models.ResponseAuth{
137
			Success: false,
138
			Message: "Failed to get the user. Try to logout/login. Otherwise, contact the support",
139
		}
140
	}
141
142
	return models.ResponseAuth{
143
		Success: true,
144
		Message: "Authenticated",
145
		User:    user,
146
	}
147
}
148
149
func CheckAuth(c *fiber.Ctx, p models.Permission) models.ResponseAuth {
150
	cookie := c.Cookies("memnix-jwt")
151
	db := database.DBConn // DB Conn
152
	token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
153
		return []byte(SecretKey), nil
154
	})
155
156
	if err != nil {
157
		c.Status(fiber.StatusUnauthorized)
158
159
		return models.ResponseAuth{
160
			Message: "Unauthenticated",
161
			Success: false,
162
		}
163
	}
164
165
	claims := token.Claims.(*jwt.StandardClaims)
166
167
	var user models.User
168
169
	if res := db.Where("id = ?", claims.Issuer).First(&user); res.Error != nil {
170
		c.Status(fiber.StatusInternalServerError)
171
		return models.ResponseAuth{
172
			Success: false,
173
			Message: "Failed to get the user. Try to logout/login. Otherwise, contact the support",
174
		}
175
	}
176
177
	if user.Permissions < p {
178
		c.Status(fiber.StatusUnauthorized)
179
		return models.ResponseAuth{
180
			Success: false,
181
			Message: "You don't have the right permissions to perform this request.",
182
		}
183
	}
184
185
	return models.ResponseAuth{
186
		Success: true,
187
		Message: "Authenticated",
188
		User:    user,
189
	}
190
}
191
192
func Logout(c *fiber.Ctx) error {
193
	auth := CheckAuth(c, models.PermUser) // Check auth
194
	if !auth.Success {
195
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
196
			Success: false,
197
			Message: auth.Message,
198
			Data:    nil,
199
			Count:   0,
200
		})
201
	}
202
203
	cookie := fiber.Cookie{
204
		Name:     "memnix-jwt",
205
		Value:    "",
206
		Expires:  time.Now().Add(-time.Hour),
207
		HTTPOnly: true,
208
		SameSite: "none",
209
		Secure:   true,
210
	}
211
	c.Cookie(&cookie)
212
213
	log := queries.CreateLog(models.LogUserLogout, "Logout: "+auth.User.Username)
214
	_ = queries.CreateUserLog(auth.User.ID, log)
215
216
	return c.JSON(fiber.Map{
217
		"message": "successfully logged out !",
218
	})
219
}
220