117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
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 MiniauthConfig struct {
|
|
LoginWithNotApprovedMail bool `env:"LOGIN_WITH_NOT_APPROVED_MAIL"`
|
|
}
|
|
|
|
type Miniauth struct {
|
|
store userstore.Store
|
|
log zerolog.Logger
|
|
smtp smtpclient.SMTPClient
|
|
config MiniauthConfig
|
|
}
|
|
|
|
func NewMiniauth(conf MiniauthConfig, 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) UserLogin(username, password string) error {
|
|
log := m.log.With().Str("func", "RegisterUser").Str("username", username).Logger()
|
|
_, err := m.store.UserCheckPassword(username, password)
|
|
if err != nil {
|
|
return utils.WrapError(ErrLoginFailed, 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
|
|
}
|