Compare commits
10 Commits
2fb3876ee6
...
40178e7fcc
| Author | SHA1 | Date |
|---|---|---|
|
|
40178e7fcc | |
|
|
5985ebcb4a | |
|
|
e9d2aeda00 | |
|
|
41eae2ccc4 | |
|
|
7a25952b1d | |
|
|
5a613d31f5 | |
|
|
ef6721af9a | |
|
|
a5901d9ac5 | |
|
|
a5fdd64877 | |
|
|
d660a030e7 |
|
|
@ -18,8 +18,11 @@ type UsersController struct {
|
|||
|
||||
func (uc *UsersController) Route() {
|
||||
rg:= uc.rg.Group("/users")
|
||||
rg.Use(middleware.RateLoginMiddleware())
|
||||
rg.Use(middleware.CORSMiddleware())
|
||||
rg.Use(middleware.RateLoginMiddleware())
|
||||
rg.OPTIONS("/login", func(c *gin.Context) {
|
||||
c.Status(http.StatusNoContent)
|
||||
})
|
||||
{
|
||||
rg.POST("/login", uc.Login())
|
||||
}
|
||||
|
|
@ -44,7 +47,7 @@ func (uc *UsersController) Login() gin.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
token, err := uc.ac.Login(login)
|
||||
token,role,name, err := uc.ac.Login(login)
|
||||
|
||||
if err != nil {
|
||||
common.ErrorResponses(c, http.StatusUnauthorized, err.Error())
|
||||
|
|
@ -52,7 +55,7 @@ func (uc *UsersController) Login() gin.HandlerFunc {
|
|||
}
|
||||
|
||||
|
||||
common.SingleResponses(c, "Login success", gin.H{"token": token})
|
||||
common.SingleResponses(c, "Login success", gin.H{"token": token, "role": role, "name": name})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CORSMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*") // Change to specific domains if needed
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
// Allow OPTIONS method to pass through
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ func getLoginLimiter() *rate.Limiter {
|
|||
|
||||
limiter, exists := rateLimiters["login"]
|
||||
if !exists {
|
||||
limiter = rate.NewLimiter(rate.Every(1*time.Minute), 4) // 5 request per second with a burst of 10 requests
|
||||
limiter = rate.NewLimiter(rate.Every(1*time.Minute), 10) // 5 request per second with a burst of 10 requests
|
||||
rateLimiters["login"] = limiter
|
||||
}
|
||||
|
||||
|
|
@ -43,6 +43,10 @@ func getLoginLimiter() *rate.Limiter {
|
|||
|
||||
func RateLimitMiddleware() gin.HandlerFunc{
|
||||
return func(c *gin.Context) {
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
userID, exists := c.Get("userID")
|
||||
if !exists {
|
||||
common.ErrorResponses(c, http.StatusUnauthorized, "Unauthorized: No user ID found")
|
||||
|
|
@ -64,6 +68,10 @@ func RateLimitMiddleware() gin.HandlerFunc{
|
|||
|
||||
func RateLoginMiddleware() gin.HandlerFunc{
|
||||
return func(c *gin.Context) {
|
||||
if c.Request.Method == http.MethodOptions {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
limiter := getLoginLimiter()
|
||||
|
||||
if !limiter.Allow() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ type TowerDTO struct {
|
|||
|
||||
type UpdateTowerDTO struct {
|
||||
DeviceID *string `json:"device_id,omitempty" validate:"omitempty,min=3"`
|
||||
TowerCode *string `json:"tower_code,omitempty" validate:"omitempty,alphanum"`
|
||||
TowerCode *string `json:"tower_code,omitempty" validate:"omitempty"`
|
||||
Longitude *float64 `json:"longitude,omitempty" validate:"omitempty,longitude"`
|
||||
Latitude *float64 `json:"latitude,omitempty" validate:"omitempty,latitude"`
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
type AuthUsecase interface {
|
||||
Login(login dto.UserLoginDTO) (string, error)
|
||||
Login(login dto.UserLoginDTO) (string,string, string ,error)
|
||||
Logout(token string) error
|
||||
}
|
||||
|
||||
|
|
@ -38,20 +38,20 @@ func NewAuthUsecase(userRepo repository.UsersRepo, cfg *config.Config) AuthUseca
|
|||
}
|
||||
}
|
||||
|
||||
func (u *authUsecase) Login(login dto.UserLoginDTO) (string, error) {
|
||||
func (u *authUsecase) Login(login dto.UserLoginDTO) (string, string, string, error) {
|
||||
err := u.validate.Struct(login)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(login)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", u.cfg.LoginAPI, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
|
@ -60,69 +60,69 @@ func (u *authUsecase) Login(login dto.UserLoginDTO) (string, error) {
|
|||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", errors.New("wrong password or username")
|
||||
return "","","", errors.New("wrong password or username")
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
var authResponse res.AuthResponses
|
||||
err = json.Unmarshal(body, &authResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
token := authResponse.Token
|
||||
|
||||
meReq, err := http.NewRequest("POST", u.cfg.AuthMeAPI, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
meReq.Header.Set("Authorization", "Bearer "+token)
|
||||
meReq.Header.Set("Accept", "application/json")
|
||||
|
||||
meResp, err := client.Do(meReq)
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "","","", err
|
||||
}
|
||||
defer meResp.Body.Close()
|
||||
|
||||
if meResp.StatusCode != http.StatusOK {
|
||||
return "", errors.New("failed to validate token: " + meResp.Status)
|
||||
return "","","", errors.New("failed to validate token: " + meResp.Status)
|
||||
}
|
||||
|
||||
meBody, err := ioutil.ReadAll(meResp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
var meResponse res.AuthMeResponse
|
||||
err = json.Unmarshal(meBody, &meResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
departemen := meResponse.Data.Departemen
|
||||
if departemen != "Teknisi" {
|
||||
return "", errors.New("user is not a technician")
|
||||
return "","","", errors.New("user is not a technician")
|
||||
}
|
||||
|
||||
role , err := u.userRepo.GetRoleByDepartment(departemen)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
password, err := utils.HashPassword(login.Password)
|
||||
if err != nil {
|
||||
return "error while hasing password: ", err
|
||||
return "error while hasing password: ","", "", err
|
||||
}
|
||||
|
||||
isUserExist, err := u.userRepo.GetUserByUsername(login.Username)
|
||||
|
|
@ -130,12 +130,12 @@ func (u *authUsecase) Login(login dto.UserLoginDTO) (string, error) {
|
|||
if isUserExist.ID != uuid.Nil {
|
||||
// Validate the password
|
||||
if !utils.CheckPasswordHash(login.Password, isUserExist.Password) {
|
||||
return "", errors.New("incorrect password")
|
||||
return "","","", errors.New("incorrect password")
|
||||
}
|
||||
|
||||
return token, nil
|
||||
return token, role.Name, isUserExist.Name, nil
|
||||
}else if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return "ERROR WHILE SEARCHING USERNAME", err
|
||||
return "ERROR WHILE SEARCHING USERNAME","", "", err
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -151,10 +151,10 @@ func (u *authUsecase) Login(login dto.UserLoginDTO) (string, error) {
|
|||
|
||||
err = u.userRepo.Post(user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "","","", err
|
||||
}
|
||||
|
||||
return token,nil
|
||||
return token, user.Role.Name, user.Name, nil
|
||||
}
|
||||
|
||||
func (u *authUsecase) Logout(token string) error {
|
||||
|
|
|
|||
Loading…
Reference in New Issue