Files
RenewCMS/internal/infrastructure/useCases/CreateUser.go
T

95 lines
2.3 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/hash"
"RenewCMS/internal/domain/mail"
"RenewCMS/internal/domain/user"
"errors"
"fmt"
"time"
"github.com/google/uuid"
)
type CreateUserUseCase struct {
userRepository user.Repository
hasher hash.Hasher
mailRepository mail.Repository
publicURL string
}
type CreateUserCommand struct {
Username string
Password string
Email string
}
type MailValidationData struct {
Host string
VerificationCode string
}
func NewCreateUserUseCase(userRepository user.Repository, hasher hash.Hasher, mailRepository mail.Repository, publicURL string) *CreateUserUseCase {
return &CreateUserUseCase{userRepository, hasher, mailRepository, publicURL}
}
func (g *CreateUserUseCase) CreateUser(createUser CreateUserCommand) (user.User, error) {
if g.registrationClosed() {
return user.User{}, user.ErrRegistrationClosed
}
rawUuid := uuid.NewString()
hashedPassword, err := g.hasher.Hash(createUser.Password)
if err != nil {
return user.User{}, err
}
hashedVerificationCode, err := g.hasher.Hash(rawUuid)
if err != nil {
return user.User{}, err
}
createdUser, err := g.userRepository.Create(user.User{
Username: createUser.Username,
Password: hashedPassword,
PasswordResetCode: "",
Email: createUser.Email,
IsVerified: false,
Role: user.RoleOwner,
VerificationCode: hashedVerificationCode,
VerificationExpiration: time.Now().Add(2 * time.Hour),
})
if err != nil {
return user.User{}, err
}
createdUser.VerificationCode = rawUuid
if err := g.mailRepository.Send(createdUser.Email, "verification", MailValidationData{
Host: g.publicURL,
VerificationCode: rawUuid,
}); err != nil {
sendErr := fmt.Errorf("failed to send verification email: %w", err)
if deleteErr := g.userRepository.Delete(createdUser.ID); deleteErr != nil {
return user.User{}, errors.Join(sendErr, deleteErr)
}
return user.User{}, sendErr
}
return createdUser, nil
}
func (g *CreateUserUseCase) IsRegistrationOpen() bool {
return !g.registrationClosed()
}
func (g *CreateUserUseCase) registrationClosed() bool {
for _, existingUser := range g.userRepository.GetAll() {
if existingUser.IsVerified {
return true
}
}
return false
}