181 lines
3.9 KiB
Go
181 lines
3.9 KiB
Go
package usecase
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"time"
|
|
"users_management/m/config"
|
|
"users_management/m/model/dto"
|
|
"users_management/m/model/dto/res"
|
|
"users_management/m/model/entity"
|
|
"users_management/m/repository"
|
|
"users_management/m/utils"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type AuthUsecase interface {
|
|
Login(login dto.UserLoginDTO) (string, error)
|
|
Logout(token string) error
|
|
}
|
|
|
|
type authUsecase struct {
|
|
userRepo repository.UsersRepo
|
|
validate *validator.Validate
|
|
cfg *config.Config
|
|
}
|
|
|
|
func NewAuthUsecase(userRepo repository.UsersRepo, cfg *config.Config) AuthUsecase {
|
|
return &authUsecase{
|
|
userRepo: userRepo,
|
|
validate: validator.New(),
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
func (u *authUsecase) Login(login dto.UserLoginDTO) (string, error) {
|
|
err := u.validate.Struct(login)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
payload, err := json.Marshal(login)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", u.cfg.LoginAPI, bytes.NewBuffer(payload))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", errors.New("wrong password or username")
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var authResponse res.AuthResponses
|
|
err = json.Unmarshal(body, &authResponse)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
token := authResponse.Token
|
|
|
|
meReq, err := http.NewRequest("POST", u.cfg.AuthMeAPI, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
meReq.Header.Set("Authorization", "Bearer "+token)
|
|
meReq.Header.Set("Accept", "application/json")
|
|
|
|
meResp, err := client.Do(meReq)
|
|
if err != nil {
|
|
return "",err
|
|
}
|
|
defer meResp.Body.Close()
|
|
|
|
if meResp.StatusCode != http.StatusOK {
|
|
return "", errors.New("failed to validate token: " + meResp.Status)
|
|
}
|
|
|
|
meBody, err := ioutil.ReadAll(meResp.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var meResponse res.AuthMeResponse
|
|
err = json.Unmarshal(meBody, &meResponse)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
departemen := meResponse.Data.Departemen
|
|
if departemen != "Teknisi" {
|
|
return "", errors.New("user is not a technician")
|
|
}
|
|
|
|
role , err := u.userRepo.GetRoleByDepartment(departemen)
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
password, err := utils.HashPassword(login.Password)
|
|
if err != nil {
|
|
return "error while hasing password: ", err
|
|
}
|
|
|
|
isUserExist, err := u.userRepo.GetUserByUsername(login.Username)
|
|
|
|
if isUserExist.ID != uuid.Nil {
|
|
// Validate the password
|
|
if !utils.CheckPasswordHash(login.Password, isUserExist.Password) {
|
|
return "", errors.New("incorrect password")
|
|
}
|
|
|
|
return token, nil
|
|
}else if err != nil && err != gorm.ErrRecordNotFound {
|
|
return "ERROR WHILE SEARCHING USERNAME", err
|
|
}
|
|
|
|
|
|
user := entity.User{
|
|
ID: uuid.New(),
|
|
Name: meResponse.Data.Nama,
|
|
Username: login.Username,
|
|
Password: password,
|
|
RoleID: role.Id,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
err = u.userRepo.Post(user)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return token,nil
|
|
}
|
|
|
|
func (u *authUsecase) Logout(token string) error {
|
|
req, err := http.NewRequest("POST", u.cfg.LogoutAPI, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return errors.New("failed to logout: " + resp.Status)
|
|
}
|
|
|
|
return nil
|
|
} |