176 lines
4.3 KiB
Go
176 lines
4.3 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"github.com/Kichiyaki/goutil/strutil"
|
|
"github.com/pkg/errors"
|
|
|
|
"gitea.dwysokinski.me/zdam-egzamin-zawodowy/backend/internal/model"
|
|
"gitea.dwysokinski.me/zdam-egzamin-zawodowy/backend/internal/user"
|
|
)
|
|
|
|
type Config struct {
|
|
UserRepository user.Repository
|
|
}
|
|
|
|
type Usecase struct {
|
|
userRepository user.Repository
|
|
}
|
|
|
|
var _ user.Usecase = &Usecase{}
|
|
|
|
func New(cfg *Config) (*Usecase, error) {
|
|
if cfg == nil || cfg.UserRepository == nil {
|
|
return nil, errors.New("cfg.UserRepository is required")
|
|
}
|
|
return &Usecase{
|
|
cfg.UserRepository,
|
|
}, nil
|
|
}
|
|
|
|
func (ucase *Usecase) Store(ctx context.Context, input *model.UserInput) (*model.User, error) {
|
|
if err := validateInput(input.Sanitize(), validateOptions{false}); err != nil {
|
|
return nil, err
|
|
}
|
|
return ucase.userRepository.Store(ctx, input)
|
|
}
|
|
|
|
func (ucase *Usecase) UpdateOneByID(ctx context.Context, id int, input *model.UserInput) (*model.User, error) {
|
|
if id <= 0 {
|
|
return nil, errors.New(messageInvalidID)
|
|
}
|
|
items, err := ucase.UpdateMany(
|
|
ctx,
|
|
&model.UserFilter{
|
|
ID: []int{id},
|
|
},
|
|
input.Sanitize(),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(items) == 0 {
|
|
return nil, errors.New(messageItemNotFound)
|
|
}
|
|
return items[0], nil
|
|
}
|
|
|
|
func (ucase *Usecase) UpdateMany(ctx context.Context, f *model.UserFilter, input *model.UserInput) ([]*model.User, error) {
|
|
if f == nil {
|
|
return []*model.User{}, nil
|
|
}
|
|
if err := validateInput(input.Sanitize(), validateOptions{true}); err != nil {
|
|
return nil, err
|
|
}
|
|
items, err := ucase.userRepository.UpdateMany(ctx, f, input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
func (ucase *Usecase) Delete(ctx context.Context, f *model.UserFilter) ([]*model.User, error) {
|
|
return ucase.userRepository.Delete(ctx, f)
|
|
}
|
|
|
|
func (ucase *Usecase) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*model.User, int, error) {
|
|
if cfg == nil {
|
|
cfg = &user.FetchConfig{
|
|
Limit: user.FetchMaxLimit,
|
|
Count: true,
|
|
}
|
|
}
|
|
if cfg.Limit > user.FetchMaxLimit || cfg.Limit <= 0 {
|
|
cfg.Limit = user.FetchMaxLimit
|
|
}
|
|
if len(cfg.Sort) > user.MaxOrders {
|
|
cfg.Sort = cfg.Sort[0:user.MaxOrders]
|
|
}
|
|
return ucase.userRepository.Fetch(ctx, cfg)
|
|
}
|
|
|
|
func (ucase *Usecase) GetByID(ctx context.Context, id int) (*model.User, error) {
|
|
items, _, err := ucase.Fetch(ctx, &user.FetchConfig{
|
|
Limit: 1,
|
|
Count: false,
|
|
Filter: &model.UserFilter{
|
|
ID: []int{id},
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(items) == 0 {
|
|
return nil, errors.New(messageItemNotFound)
|
|
}
|
|
return items[0], nil
|
|
}
|
|
|
|
func (ucase *Usecase) GetByCredentials(ctx context.Context, email, password string) (*model.User, error) {
|
|
items, _, err := ucase.Fetch(ctx, &user.FetchConfig{
|
|
Limit: 1,
|
|
Count: false,
|
|
Filter: &model.UserFilter{
|
|
Email: []string{email},
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(items) == 0 {
|
|
return nil, errors.New(messageInvalidCredentials)
|
|
}
|
|
if err := items[0].CompareHashAndPassword(password); err != nil {
|
|
return nil, errors.New(messageInvalidCredentials)
|
|
}
|
|
return items[0], nil
|
|
}
|
|
|
|
type validateOptions struct {
|
|
acceptNilValues bool
|
|
}
|
|
|
|
func validateInput(input *model.UserInput, opts validateOptions) error {
|
|
if input.IsEmpty() {
|
|
return errors.New(messageEmptyPayload)
|
|
}
|
|
|
|
if input.DisplayName != nil {
|
|
displayNameLength := len(*input.DisplayName)
|
|
if displayNameLength < user.MinDisplayNameLength {
|
|
return errors.New(messageDisplayNameIsRequired)
|
|
} else if displayNameLength > user.MaxDisplayNameLength {
|
|
return errors.Errorf(messageDisplayNameIsTooLong, user.MaxDisplayNameLength)
|
|
}
|
|
} else if !opts.acceptNilValues {
|
|
return errors.New(messageDisplayNameIsRequired)
|
|
}
|
|
|
|
if input.Email != nil {
|
|
if !strutil.IsEmail(*input.Email) {
|
|
return errors.New(messageEmailIsInvalid)
|
|
}
|
|
} else if !opts.acceptNilValues {
|
|
return errors.New(messageEmailIsRequired)
|
|
}
|
|
|
|
if input.Password != nil {
|
|
passwordLength := len(*input.Password)
|
|
if passwordLength > user.MaxPasswordLength || passwordLength < user.MinPasswordLength {
|
|
return errors.Errorf(messagePasswordInvalidLength, user.MinPasswordLength, user.MaxPasswordLength)
|
|
}
|
|
} else if !opts.acceptNilValues {
|
|
return errors.New(messagePasswordIsRequired)
|
|
}
|
|
|
|
if input.Role != nil {
|
|
if !input.Role.IsValid() {
|
|
return errors.New(messageInvalidRole)
|
|
}
|
|
} else if !opts.acceptNilValues {
|
|
return errors.New(messageInvalidRole)
|
|
}
|
|
|
|
return nil
|
|
}
|