129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
package users
|
|
|
|
import (
|
|
"src.dualinventive.com/go/lib/dilog"
|
|
"src.dualinventive.com/go/mtinfo-go"
|
|
"src.dualinventive.com/go/users-service/errors"
|
|
"src.dualinventive.com/go/users-service/internal/domain"
|
|
"src.dualinventive.com/go/users-service/internal/storage"
|
|
)
|
|
|
|
//UserService contains User related operations.
|
|
type UserService struct {
|
|
Logger dilog.Logger
|
|
UserRepository storage.UserRepository
|
|
Mtinfo *mtinfo.Client
|
|
}
|
|
|
|
//GetUserByID returns a user by the given userID, or returns an error.
|
|
func (s *UserService) GetUserByID(token string, userID uint64) (*domain.User, error) {
|
|
err := s.verifyToken(token)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
user, err := s.UserRepository.GetUserByID(userID)
|
|
if err != nil {
|
|
s.Logger.WithError(err).Error("failed to fetch user")
|
|
return nil, errors.NewErrUserRepositoryErr("failed to fetch user", err)
|
|
}
|
|
if user == nil {
|
|
s.Logger.WithField("userID", userID).Warning("user not found")
|
|
return nil, errors.NewErrUserNotFound()
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
//ListUsers returns users based on filter, paginated and sorted or nil if not found.
|
|
func (s *UserService) ListUsers(
|
|
token string, filter domain.UsersFilter, page uint64, perPage uint64, sort domain.SortCol,
|
|
) ([]domain.User, uint64, error) {
|
|
err := s.verifyToken(token)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Check filter params
|
|
filter, err = s.checkFilterParam(filter)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Check pagination params
|
|
err = s.checkPaginationParam(page, perPage)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Check user
|
|
me, err := s.Mtinfo.Auth.Me(token)
|
|
if err != nil {
|
|
s.Logger.WithError(err).Error("failed to fetch me")
|
|
return nil, 0, errors.NewErrUserRepositoryErr("failed to fetch me", err)
|
|
}
|
|
filter[domain.UsersFilterTypeCompanyID] = uint64(me.Company.ID)
|
|
|
|
users, count, err := s.UserRepository.ListUsers(filter, page, perPage, sort)
|
|
if err != nil {
|
|
s.Logger.WithFields(dilog.Fields{
|
|
"page": page,
|
|
"per_page": perPage,
|
|
"sort": sort,
|
|
}).WithError(err).Error("failed to fetch users")
|
|
return nil, 0, errors.NewErrUserRepositoryErr("failed to fetch users", err)
|
|
}
|
|
|
|
return users, count, nil
|
|
}
|
|
|
|
func (s *UserService) verifyToken(token string) error {
|
|
ok, err := s.Mtinfo.Auth.VerifyToken(token)
|
|
if err != nil {
|
|
s.Logger.WithField("token", token).WithError(err).Warning("unauthorized with error")
|
|
return errors.NewErrUnauthorized()
|
|
}
|
|
if !ok {
|
|
s.Logger.WithField("token", token).Warning("unauthorized")
|
|
return errors.NewErrUnauthorized()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *UserService) checkFilterParam(filter domain.UsersFilter) (domain.UsersFilter, error) {
|
|
if filter == nil {
|
|
filter = make(domain.UsersFilter)
|
|
}
|
|
reference, found := filter[domain.UsersFilterTypeReference]
|
|
if found {
|
|
if len(reference.(string)) == 0 {
|
|
return nil, errors.NewErrInvalidArgument(
|
|
domain.UsersFilterTypeReference.String(), "can not be empty",
|
|
)
|
|
}
|
|
if len(reference.(string)) > 30 {
|
|
return nil, errors.NewErrInvalidArgument(
|
|
domain.UsersFilterTypeReference.String(), "string length max. 30 characters",
|
|
)
|
|
}
|
|
}
|
|
|
|
return filter, nil
|
|
}
|
|
|
|
func (s *UserService) checkPaginationParam(page uint64, perPage uint64) error {
|
|
if page == 0 {
|
|
return errors.NewErrInvalidArgument("page", "can not be 0")
|
|
}
|
|
|
|
if perPage == 0 {
|
|
return errors.NewErrInvalidArgument("per_page", "can not be 0")
|
|
}
|
|
if perPage > 200 {
|
|
return errors.NewErrInvalidArgument("per_page", "can not be > 200")
|
|
}
|
|
|
|
return nil
|
|
}
|