Passed
Push — main ( f6597a...58b626 )
by Yume
01:31 queued 12s
created

auth.*UseCase.RefreshToken   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
package auth
2
3
import (
4
	"strings"
5
6
	"github.com/memnix/memnix-rest/domain"
7
	"github.com/memnix/memnix-rest/internal/user"
8
	"github.com/memnix/memnix-rest/pkg/jwt"
9
	"github.com/pkg/errors"
10
	"github.com/rs/zerolog/log"
11
	"golang.org/x/crypto/bcrypt"
12
	"gorm.io/gorm"
13
)
14
15
type UseCase struct {
16
	user.IRepository
17
}
18
19
func NewUseCase(repo user.IRepository) IUseCase {
20
	return &UseCase{IRepository: repo}
21
}
22
23
// Login logs in a user
24
// Returns a token and error
25
func (a *UseCase) Login(password string, email string) (string, error) {
26
	userModel, err := a.GetByEmail(email)
27
	if err != nil {
28
		return "", errors.New("user not found")
29
	}
30
31
	ok, err := ComparePasswords(password, []byte(userModel.Password))
32
	if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) || !ok {
33
		return "", errors.New("invalid password")
34
	}
35
	if err != nil {
36
		return "", err
37
	}
38
39
	token, err := jwt.GenerateToken(userModel.ID)
40
	if err != nil {
41
		return "", err
42
	}
43
44
	return token, nil
45
}
46
47
// Register registers a new user
48
// Returns an error
49
func (a *UseCase) Register(registerStruct domain.Register) (domain.User, error) {
50
	if err := VerifyPassword(registerStruct.Password); err != nil {
51
		return domain.User{}, errors.Wrap(err, "Verify password failed")
52
	}
53
54
	hash, err := GenerateEncryptedPassword(registerStruct.Password)
55
	if err != nil {
56
		return domain.User{}, errors.Wrap(err, "Generate encrypted password failed")
57
	}
58
59
	registerStruct.Password = string(hash)
60
	registerStruct.Email = strings.ToLower(registerStruct.Email)
61
	userModel := registerStruct.ToUser()
62
63
	if err = a.Create(&userModel); err != nil {
64
		log.Warn().Err(err).Msg("failed to create user in register")
65
		return domain.User{}, errors.Wrap(err, "failed to create registerStruct in register")
66
	}
67
68
	userModel, err = a.GetByEmail(registerStruct.Email)
69
	if err != nil {
70
		return domain.User{}, errors.Wrap(err, "failed to get registerStruct in register")
71
	}
72
73
	return userModel, nil
74
}
75
76
// Logout returns an empty string
77
// It might be used to invalidate a token in the future
78
func (a *UseCase) Logout() (string, error) {
79
	return "", nil
80
}
81
82
// RefreshToken refreshes a token
83
func (a *UseCase) RefreshToken(user domain.User) (string, error) {
84
	token, err := jwt.GenerateToken(user.ID)
85
	if err != nil {
86
		return "", err
87
	}
88
89
	return token, nil
90
}
91
92
func (a *UseCase) RegisterOauth(user domain.User) error {
93
	return a.Create(&user)
94
}
95
96
func (a *UseCase) LoginOauth(user domain.User) (string, error) {
97
	userModel, err := a.GetByEmail(user.Email)
98
	if err != nil {
99
		if errors.Is(err, gorm.ErrRecordNotFound) {
100
			err = a.RegisterOauth(user)
101
			if err != nil {
102
				log.Error().Err(err).Msg("failed to register user")
103
				return "", errors.New("failed to register user")
104
			}
105
		} else {
106
			log.Error().Err(err).Msg("failed to get user")
107
			return "", errors.New("failed to get user")
108
		}
109
	}
110
111
	if userModel.OauthProvider != user.OauthProvider && userModel.OauthProvider != "" {
112
		log.Error().Err(err).Msg("user is already registered with another provider")
113
		return "", errors.New("user is already registered with another provider")
114
	}
115
116
	// Check if user is up to date
117
	if userModel.OauthID == "" {
118
		userModel.OauthID = user.OauthID
119
		userModel.OauthProvider = user.OauthProvider
120
		if user.Avatar != "" {
121
			userModel.Avatar = user.Avatar
122
		}
123
		err = a.Update(&userModel)
124
		if err != nil {
125
			log.Error().Err(err).Msg("failed to update user")
126
			return "", errors.New("failed to update user")
127
		}
128
	}
129
130
	return jwt.GenerateToken(userModel.ID)
131
}
132