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
|
package services
import (
"shrine/enums"
"shrine/messages"
"shrine/models"
"shrine/repositories"
"shrine/types/account"
"shrine/types/common"
"shrine/types/hypertext"
"shrine/utils/crypto"
)
func Register(request account.RegisterRequest, ip string) (*common.MessageResponse, *hypertext.ServiceError) {
if repositories.IsIPBanned(ip) {
return nil, fail(enums.Forbidden, messages.IPBanned)
}
citizen := models.User{
Username: request.Username,
Email: request.Email,
DisplayName: request.DisplayName,
IP: ip,
}
if err := citizen.SetPassword(request.Password); err != nil {
return nil, fail(enums.BadRequest, err.Error())
}
if err := repositories.CreateUser(&citizen); err != nil {
return nil, mapRegistrationError(err)
}
if serviceErr := SendVerification(&citizen, enums.Activation); serviceErr != nil {
return nil, serviceErr
}
return &common.MessageResponse{Message: messages.AccountCreated}, nil
}
func Authenticate(request account.LoginRequest, ip string) (*models.User, *hypertext.ServiceError) {
citizen, err := repositories.FindUserByUsername(request.Username)
if err != nil {
return nil, fail(enums.Unauthorized, messages.InvalidUsernameOrPassword)
}
if !citizen.IsStaff() && repositories.IsIPBanned(ip) {
return nil, fail(enums.Forbidden, messages.IPBanned)
}
if citizen.ClearExpiredDisable() {
repositories.UpdateUser(citizen)
}
if !citizen.CanAuthenticate() {
return nil, fail(enums.Forbidden, messages.AccountBannedOrDisabled)
}
if !citizen.CheckPassword(request.Password) {
return nil, fail(enums.Unauthorized, messages.InvalidUsernameOrPassword)
}
if !citizen.IsVerified() {
return nil, fail(enums.Forbidden, messages.EmailNotVerified)
}
citizen.IP = ip
repositories.UpdateUser(citizen)
return citizen, nil
}
func VerifyAccount(request account.VerifyRequest) (*common.MessageResponse, *hypertext.ServiceError) {
if request.Token == "" {
return nil, fail(enums.BadRequest, messages.VerificationTokenRequired)
}
verificationType := enums.VerificationType(request.Type)
citizen, err := repositories.FindUserByVerification(crypto.HashToken(request.Token), verificationType)
if err != nil {
return nil, fail(enums.BadRequest, messages.VerificationLinkInvalid)
}
switch verificationType {
case enums.Activation:
citizen.VerifyEmail()
default:
return nil, fail(enums.BadRequest, messages.InvalidVerificationType)
}
if err := repositories.UpdateUser(citizen); err != nil {
return nil, fail(enums.Internal, messages.FailedVerifyAccount)
}
return &common.MessageResponse{Message: messages.EmailVerified}, nil
}
func ResendActivation(request account.ResendActivationRequest) (*common.MessageResponse, *hypertext.ServiceError) {
citizen, err := repositories.FindUserByEmail(request.Email)
if err != nil {
return nil, fail(enums.BadRequest, messages.NoAccountWithEmail)
}
if citizen.IsVerified() {
return nil, fail(enums.BadRequest, messages.AccountAlreadyVerified)
}
if serviceErr := SendVerification(citizen, enums.Activation); serviceErr != nil {
return nil, serviceErr
}
return &common.MessageResponse{Message: messages.VerificationEmailSent}, nil
}
func RevokeToken(tokenHash string) (*common.MessageResponse, *hypertext.ServiceError) {
if err := repositories.DeleteToken(tokenHash); err != nil {
return nil, fail(enums.Internal, messages.FailedEndSession)
}
return &common.MessageResponse{Message: messages.LoggedOut}, nil
}
|