ms-auth/internal/services/user.go
2024-08-14 20:24:57 +05:00

132 lines
3.1 KiB
Go

package services
import (
"context"
"git.sch9.ru/new_gate/ms-auth/internal/lib"
"git.sch9.ru/new_gate/ms-auth/internal/models"
)
type UserStorage interface {
CreateUser(ctx context.Context, user *models.User) (int32, error)
ReadUserByEmail(ctx context.Context, email string) (*models.User, error)
ReadUserByUsername(ctx context.Context, username string) (*models.User, error)
ReadUserById(ctx context.Context, id int32) (*models.User, error)
UpdateUser(ctx context.Context, user *models.User) error
DeleteUser(ctx context.Context, id int32) error
}
type UserService struct {
userProvider UserStorage
sessionProvider SessionProvider
cfg lib.Config
}
func NewUserService(
userProvider UserStorage,
sessionProvider SessionProvider,
cfg lib.Config,
) *UserService {
return &UserService{
userProvider: userProvider,
sessionProvider: sessionProvider,
cfg: cfg,
}
}
func (u *UserService) CreateUser(ctx context.Context, user *models.User) (int32, error) {
me := ctx.Value("user").(*models.User)
switch *me.Role {
case models.RoleAdmin:
break
case models.RoleModerator:
if !user.Role.AtMost(models.RoleParticipant) {
return 0, lib.ErrNoPermission
}
default:
return 0, lib.ErrNoPermission
}
return u.userProvider.CreateUser(ctx, user)
}
func (u *UserService) ReadUserBySessionToken(ctx context.Context, token string) (*models.User, error) {
session, err := u.sessionProvider.ReadSessionByToken(ctx, token)
if err != nil {
return nil, err
}
return u.userProvider.ReadUserById(ctx, *session.UserId)
}
func (u *UserService) ReadUser(ctx context.Context, id int32) (*models.User, error) {
return u.userProvider.ReadUserById(ctx, id)
}
func (u *UserService) ReadUserByEmail(ctx context.Context, email string) (*models.User, error) {
return u.userProvider.ReadUserByEmail(ctx, email)
}
func (u *UserService) ReadUserByUsername(ctx context.Context, username string) (*models.User, error) {
return u.userProvider.ReadUserByUsername(ctx, username)
}
func (u *UserService) UpdateUser(ctx context.Context, modifiedUser *models.User) error {
me := ctx.Value("user").(*models.User)
user, err := u.userProvider.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 lib.ErrNoPermission
}
return u.userProvider.UpdateUser(ctx, user)
}
func (u *UserService) DeleteUser(ctx context.Context, id int32) error {
me := ctx.Value("user").(*models.User)
if *me.Id == id || !me.Role.IsAdmin() {
return lib.ErrNoPermission
}
return u.userProvider.DeleteUser(ctx, id)
}