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) }