Initial commit: Эфир мессенджер
This commit is contained in:
180
internal/service/admin_service.go
Normal file
180
internal/service/admin_service.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"messenger/internal/models"
|
||||
"messenger/internal/pkg/logger"
|
||||
"messenger/internal/repository"
|
||||
)
|
||||
|
||||
type AdminService struct {
|
||||
userRepo repository.UserRepository
|
||||
chatRepo repository.ChatRepository
|
||||
messageRepo repository.MessageRepository
|
||||
fileService *FileService
|
||||
}
|
||||
|
||||
func NewAdminService(
|
||||
userRepo repository.UserRepository,
|
||||
chatRepo repository.ChatRepository,
|
||||
messageRepo repository.MessageRepository,
|
||||
fileService *FileService,
|
||||
) *AdminService {
|
||||
return &AdminService{
|
||||
userRepo: userRepo,
|
||||
chatRepo: chatRepo,
|
||||
messageRepo: messageRepo,
|
||||
fileService: fileService,
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteUser удаляет пользователя (каскадно)
|
||||
func (s *AdminService) DeleteUser(ctx context.Context, adminUserID, targetUserID int64) error {
|
||||
// Проверяем, что администратор имеет права
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return errors.New("only global admin can delete users")
|
||||
}
|
||||
|
||||
// Нельзя удалить самого себя через эту функцию
|
||||
if adminUserID == targetUserID {
|
||||
return errors.New("cannot delete yourself")
|
||||
}
|
||||
|
||||
// Проверяем существование пользователя
|
||||
target, err := s.userRepo.FindByID(ctx, targetUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if target == nil {
|
||||
return errors.New("user not found")
|
||||
}
|
||||
|
||||
// Удаляем пользователя (каскадное удаление сработает через foreign keys)
|
||||
if err := s.userRepo.Delete(ctx, targetUserID); err != nil {
|
||||
logger.Error("Failed to delete user", "error", err)
|
||||
return errors.New("failed to delete user")
|
||||
}
|
||||
|
||||
logger.Info("User deleted by admin", "admin_id", adminUserID, "target_user_id", targetUserID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteMessage удаляет любое сообщение (админское право)
|
||||
func (s *AdminService) DeleteMessage(ctx context.Context, adminUserID, messageID int64) error {
|
||||
// Проверяем права администратора
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return errors.New("only global admin can delete any message")
|
||||
}
|
||||
|
||||
if err := s.messageRepo.Delete(ctx, messageID); err != nil {
|
||||
logger.Error("Failed to delete message by admin", "error", err)
|
||||
return errors.New("failed to delete message")
|
||||
}
|
||||
|
||||
logger.Info("Message deleted by admin", "admin_id", adminUserID, "message_id", messageID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteChat удаляет любой чат (админское право)
|
||||
func (s *AdminService) DeleteChat(ctx context.Context, adminUserID, chatID int64) error {
|
||||
// Проверяем права администратора
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return errors.New("only global admin can delete any chat")
|
||||
}
|
||||
|
||||
if err := s.chatRepo.Delete(ctx, chatID); err != nil {
|
||||
logger.Error("Failed to delete chat by admin", "error", err)
|
||||
return errors.New("failed to delete chat")
|
||||
}
|
||||
|
||||
logger.Info("Chat deleted by admin", "admin_id", adminUserID, "chat_id", chatID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// PromoteToAdmin повышает пользователя до глобального администратора
|
||||
func (s *AdminService) PromoteToAdmin(ctx context.Context, adminUserID, targetUserID int64) error {
|
||||
// Проверяем права администратора
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return errors.New("only global admin can promote users")
|
||||
}
|
||||
|
||||
if err := s.userRepo.UpdateRole(ctx, targetUserID, models.RoleGlobalAdmin); err != nil {
|
||||
logger.Error("Failed to promote user to admin", "error", err)
|
||||
return errors.New("failed to promote user")
|
||||
}
|
||||
|
||||
logger.Info("User promoted to global admin", "admin_id", adminUserID, "target_user_id", targetUserID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DemoteFromAdmin понижает глобального администратора до обычного пользователя
|
||||
func (s *AdminService) DemoteFromAdmin(ctx context.Context, adminUserID, targetUserID int64) error {
|
||||
// Проверяем права администратора
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return errors.New("only global admin can demote users")
|
||||
}
|
||||
|
||||
// Нельзя понизить самого себя
|
||||
if adminUserID == targetUserID {
|
||||
return errors.New("cannot demote yourself")
|
||||
}
|
||||
|
||||
if err := s.userRepo.UpdateRole(ctx, targetUserID, models.RoleUser); err != nil {
|
||||
logger.Error("Failed to demote user", "error", err)
|
||||
return errors.New("failed to demote user")
|
||||
}
|
||||
|
||||
logger.Info("User demoted from global admin", "admin_id", adminUserID, "target_user_id", targetUserID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSystemStats возвращает системную статистику
|
||||
func (s *AdminService) GetSystemStats(ctx context.Context, adminUserID int64) (map[string]interface{}, error) {
|
||||
// Проверяем права администратора
|
||||
admin, err := s.userRepo.FindByID(ctx, adminUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if admin == nil || !admin.IsGlobalAdmin() {
|
||||
return nil, errors.New("only global admin can view system stats")
|
||||
}
|
||||
|
||||
// Здесь можно добавить реальную статистику из БД
|
||||
// Например, количество пользователей, сообщений, чатов и т.д.
|
||||
stats := make(map[string]interface{})
|
||||
|
||||
// Это заглушка - в реальном коде нужно добавить методы в репозитории
|
||||
stats["version"] = "1.0.0"
|
||||
stats["status"] = "healthy"
|
||||
|
||||
logger.Info("System stats viewed by admin", "admin_id", adminUserID)
|
||||
return stats, nil
|
||||
}
|
||||
Reference in New Issue
Block a user