ms-auth/internal/users/usecase/usecase.go

150 lines
3.1 KiB
Go
Raw Normal View History

2024-10-09 17:07:38 +00:00
package usecase
import (
"context"
"git.sch9.ru/new_gate/ms-auth/config"
"git.sch9.ru/new_gate/ms-auth/internal/models"
"git.sch9.ru/new_gate/ms-auth/internal/sessions"
"git.sch9.ru/new_gate/ms-auth/internal/users"
"git.sch9.ru/new_gate/ms-auth/pkg/utils"
)
type useCase struct {
userRepo users.PgRepository
sessionProvider sessions.ValkeyRepository
cfg config.Config
}
func NewUseCase(
userRepo users.PgRepository,
sessionRepo sessions.ValkeyRepository,
cfg config.Config,
) *useCase {
return &useCase{
userRepo: userRepo,
sessionProvider: sessionRepo,
cfg: cfg,
}
}
func (u *useCase) CreateUser(ctx context.Context, user *models.User) (int32, error) {
meId, ok := ctx.Value("userId").(*int32)
if !ok {
return 0, utils.ErrNoPermission
}
me, err := u.ReadUser(ctx, *meId)
if err != nil {
return 0, err
}
switch *me.Role {
case models.RoleAdmin:
break
case models.RoleModerator:
if !user.Role.AtMost(models.RoleParticipant) {
return 0, utils.ErrNoPermission
}
default:
return 0, utils.ErrNoPermission
}
return u.userRepo.CreateUser(ctx, user)
}
func (u *useCase) ReadUserBySessionToken(ctx context.Context, token string) (*models.User, error) {
session, err := u.sessionProvider.ReadSessionByToken(ctx, token)
if err != nil {
return nil, err
}
return u.userRepo.ReadUserById(ctx, *session.UserId)
}
func (u *useCase) ReadUser(ctx context.Context, id int32) (*models.User, error) {
return u.userRepo.ReadUserById(ctx, id)
}
func (u *useCase) ReadUserByEmail(ctx context.Context, email string) (*models.User, error) {
return u.userRepo.ReadUserByEmail(ctx, email)
}
func (u *useCase) ReadUserByUsername(ctx context.Context, username string) (*models.User, error) {
return u.userRepo.ReadUserByUsername(ctx, username)
}
func (u *useCase) UpdateUser(ctx context.Context, modifiedUser *models.User) error {
meId, ok := ctx.Value("userId").(*int32)
if !ok {
return utils.ErrNoPermission
}
me, err := u.ReadUser(ctx, *meId)
if err != nil {
return err
}
user, err := u.userRepo.ReadUserById(ctx, *modifiedUser.Id)
if err != nil {
return err
}
hasAccess := func() bool {
if me.Role.IsAdmin() {
return true
}
if me.Role.IsModerator() {
if !user.Role.AtMost(models.RoleParticipant) {
return false
}
return true
}
if me.Role.IsParticipant() {
if me.Id != user.Id {
return false
}
if modifiedUser.Username != nil {
return false
}
if modifiedUser.Email != nil {
return false
}
if modifiedUser.ExpiresAt != nil {
return false
}
if modifiedUser.Role != nil {
return false
}
return true
}
if me.Role.IsSpectator() {
return false
}
return false
}()
if !hasAccess {
return utils.ErrNoPermission
}
return u.userRepo.UpdateUser(ctx, user)
}
func (u *useCase) DeleteUser(ctx context.Context, id int32) error {
userId, ok := ctx.Value("userId").(*int32)
if !ok {
return utils.ErrNoPermission
}
me, err := u.ReadUser(ctx, *userId)
if err != nil {
return err
}
if *me.Id == id || !me.Role.IsAdmin() {
return utils.ErrNoPermission
}
return u.userRepo.DeleteUser(ctx, id)
}