diff options
Diffstat (limited to 'pkg/service/user/register.go')
-rw-r--r-- | pkg/service/user/register.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/pkg/service/user/register.go b/pkg/service/user/register.go new file mode 100644 index 0000000..69f19a2 --- /dev/null +++ b/pkg/service/user/register.go @@ -0,0 +1,85 @@ +package user + +import ( + "context" + "errors" + "regexp" + + normalizer "github.com/dimuska139/go-email-normalizer/v3" + "github.com/uptrace/bun/driver/pgdriver" + "golang.org/x/crypto/bcrypt" + + "go.neonxp.ru/framework/pkg/model" + "go.neonxp.ru/framework/pkg/tpl" +) + +var ( + ErrUsernameToShort = errors.New("username_to_short") + ErrUserAlreadyExist = errors.New("user_already_exists") + ErrPasswordTooWeak = errors.New("password_too_weak") + ErrPasswordTooShort = errors.New("password_too_short") +) + +const ( + minUsernameLen = 3 + minPasswordLen = 8 +) + +func (s *Service) Register(ctx context.Context, form *tpl.RegisterForm) (*model.User, error) { + if len(form.Username) < minUsernameLen { + return nil, ErrUsernameToShort + } + + if err := checkPasswordLever(form.Password); err != nil { + return nil, err + } + + password, err := bcrypt.GenerateFromPassword([]byte(form.Password), bcrypt.DefaultCost) + if err != nil { + return nil, err + } + + n := normalizer.NewNormalizer() + u := &model.User{ + Username: form.Username, + Email: n.Normalize(form.Email), + Password: string(password), + } + + if _, err := s.db.NewInsert().Model(u).Returning("*").Exec(ctx); err != nil { + pqErr := pgdriver.Error{} + if errors.As(err, &pqErr) { + if pqErr.Field('C') == "23505" { + return nil, ErrUserAlreadyExist + } + } + + return nil, err + } + + return u, nil +} + +func checkPasswordLever(ps string) error { + if len(ps) < minPasswordLen { + return ErrPasswordTooShort + } + + lowerCase := `[a-z]{1}` + upperCase := `[A-Z]{1}` + symbol := `[0-9!@#~$%^&*()+|_]{1}` + + if b, err := regexp.MatchString(lowerCase, ps); !b || err != nil { + return ErrPasswordTooWeak + } + + if b, err := regexp.MatchString(upperCase, ps); !b || err != nil { + return ErrPasswordTooWeak + } + + if b, err := regexp.MatchString(symbol, ps); !b || err != nil { + return ErrPasswordTooWeak + } + + return nil +} |