package miniauth import ( "errors" "net/mail" "regexp" "git.keks.cloud/kekskurse/miniauth/pkg/smtpclient" "git.keks.cloud/kekskurse/miniauth/pkg/userstore" "git.keks.cloud/kekskurse/miniauth/pkg/utils" "github.com/go-passwd/validator" "github.com/rs/zerolog" ) type Miniauth struct { store userstore.Store log zerolog.Logger smtp smtpclient.SMTPClient } func NewMiniauth(us userstore.Store, sm smtpclient.SMTPClient) Miniauth { m := Miniauth{} m.store = us m.smtp = sm return m } func (m Miniauth) RegisterUser(username string, email string, password string) error { log := m.log.With().Str("func", "RegisterUser").Str("username", username).Str("mail", email).Logger() err := m.checkUsernameForRegistration(username) if err != nil { return utils.WrapError(ErrUserHasInvalideChars, err, log) } err = m.checkPasswordForRegistration(password) if err != nil { return utils.WrapError(ErrPasswordNotComplexEnough, err, log) } _, err = mail.ParseAddress(email) if err != nil { return utils.WrapError(ErrMailAddressInvalide, err, log) } used, err := m.store.MailCheckExists(email) if err != nil { return utils.WrapError(ErrMailAddressInvalide, err, log) } if used { return utils.WrapError(ErrMailAddressInvalide, errors.New("email alreadys used"), log) } id, err := m.store.UserWrite(username, password) if err != nil { return utils.WrapError(ErrCantCreateUser, err, log) } log = log.With().Int64("userid", id).Logger() err = m.store.MailAdd(email, id, true) if err != nil { return utils.WrapError(ErrCantCreateUser, err, log) } err = m.smtp.SendMail("register", email, map[string]any{"hash": "abc"}) if err != nil { m.store.MailRemove(email) m.store.UserDelete(username) return utils.WrapError(ErrCantSendMail, err, log) } return nil } func (m Miniauth) checkPasswordForRegistration(password string) error { passwordValidator := validator.New( validator.MinLength(15, nil), validator.ContainsAtLeast("abcdefghijklmnopqrstuvwxyz", 5, nil), validator.ContainsAtLeast("0123456789", 3, nil), validator.ContainsAtLeast(",;.:-_#+*?=}])[({/&%$ยง!<>|", 3, nil)) err := passwordValidator.Validate(password) return err } func (m Miniauth) checkUsernameForRegistration(username string) error { reg := regexp.MustCompile("^[a-z0-9]{4,25}$") if !reg.MatchString(username) { return ErrUserHasInvalideChars } exists, err := m.store.UserExists(username) if err != nil { return err } if exists { return ErrUsernameIsTaken } return nil }