This repository has been archived on 2025-10-08. You can view files and clone it, but cannot push or open issues or pull requests.
miniauthold/pkg/miniauth/miniauth.go
kekskurse 19dab2268e
Some checks failed
ci/woodpecker/push/test Pipeline failed
ci/woodpecker/push/playwright unknown status
ci/woodpecker/push/deplyoment unknown status
chore: login methode return user
2025-05-25 20:41:22 +02:00

137 lines
3.4 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"
"github.com/rs/zerolog/log"
)
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
}
type User struct {
userstore.User
}
func NewMiniauth(conf MiniauthConfig, us userstore.Store, sm smtpclient.SMTPClient) Miniauth {
m := Miniauth{}
m.store = us
m.smtp = sm
m.config = conf
m.log = log.With().Str("pkg", "miniauth").Logger()
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) (User, error) {
log := m.log.With().Str("func", "RegisterUser").Str("username", username).Logger()
userdata, err := m.store.UserCheckPassword(username, password)
if err != nil {
return User{}, utils.WrapError(ErrLoginFailed, err, log)
}
if !m.config.LoginWithNotApprovedMail {
mail, err := m.store.MailGetPrimaryForUsername(username)
if err != nil {
return User{}, utils.WrapError(ErrLoginFailed, err, log)
}
if !mail.IsValidated {
return User{}, utils.WrapError(ErrLoginFailed, errors.New("mail is not validated"), log)
}
}
u := User{}
u.User = userdata
return u, 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
}