summaryrefslogtreecommitdiff
path: root/shrine/services/auth.go
diff options
context:
space:
mode:
Diffstat (limited to 'shrine/services/auth.go')
-rw-r--r--shrine/services/auth.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/shrine/services/auth.go b/shrine/services/auth.go
new file mode 100644
index 0000000..28e63c4
--- /dev/null
+++ b/shrine/services/auth.go
@@ -0,0 +1,108 @@
+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) (*common.MessageResponse, *hypertext.ServiceError) {
+ citizen := models.User{
+ Username: request.Username,
+ Email: request.Email,
+ DisplayName: request.DisplayName,
+ }
+
+ 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) (*models.User, *hypertext.ServiceError) {
+ citizen, err := repositories.FindUserByUsername(request.Username)
+ if err != nil {
+ return nil, fail(enums.Unauthorized, messages.InvalidUsernameOrPassword)
+ }
+
+ 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)
+ }
+
+ 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
+} \ No newline at end of file