Files
rmser/internal/infrastructure/rms/factory.go
SERTY b4ce819931 добавил пользователей для сервера и роли
добавил инвайт-ссылки с ролью оператор для сервера
добавил супер-админку для смены владельцев
добавил уведомления о смене ролей на серверах
добавил модалку для фото прям в черновике
добавил UI для редактирования прав
2025-12-23 13:06:06 +03:00

97 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package rms
import (
"fmt"
"sync"
"github.com/google/uuid"
"go.uber.org/zap"
"rmser/internal/domain/account"
"rmser/pkg/crypto"
"rmser/pkg/logger"
)
// Factory управляет созданием и переиспользованием клиентов RMS
type Factory struct {
accountRepo account.Repository
cryptoManager *crypto.CryptoManager
// Кэш активных клиентов: ServerID -> *Client
mu sync.RWMutex
clients map[uuid.UUID]*Client
}
func NewFactory(repo account.Repository, cm *crypto.CryptoManager) *Factory {
return &Factory{
accountRepo: repo,
cryptoManager: cm,
clients: make(map[uuid.UUID]*Client),
}
}
// GetClientForUser возвращает клиент для текущего активного сервера пользователя.
// Использует личные или наследуемые (от Owner) учетные данные.
func (f *Factory) GetClientForUser(userID uuid.UUID) (ClientI, error) {
// 1. Пытаемся найти в кэше
f.mu.RLock()
client, exists := f.clients[userID]
f.mu.RUnlock()
if exists {
return client, nil
}
// 2. Создаем новый клиент под блокировкой
f.mu.Lock()
defer f.mu.Unlock()
// Double check
if client, exists := f.clients[userID]; exists {
return client, nil
}
// 3. Получаем креды из репозитория (учитывая фоллбэк на Owner'а)
baseURL, login, encryptedPass, err := f.accountRepo.GetActiveConnectionCredentials(userID)
if err != nil {
return nil, fmt.Errorf("ошибка получения настроек подключения: %w", err)
}
// 4. Расшифровка пароля
plainPass, err := f.cryptoManager.Decrypt(encryptedPass)
if err != nil {
return nil, fmt.Errorf("ошибка расшифровки пароля RMS: %w", err)
}
// 5. Создание клиента
newClient := NewClient(baseURL, login, plainPass)
f.clients[userID] = newClient
logger.Log.Info("RMS Factory: Client created for user",
zap.String("user_id", userID.String()),
zap.String("login", login),
zap.String("url", baseURL))
return newClient, nil
}
// CreateClientFromRawCredentials создает клиент без сохранения в кэш (для тестов подключения)
func (f *Factory) CreateClientFromRawCredentials(url, login, password string) *Client {
return NewClient(url, login, password)
}
// ClearCacheForUser сбрасывает кэш пользователя (при смене сервера или выходе)
func (f *Factory) ClearCacheForUser(userID uuid.UUID) {
f.mu.Lock()
defer f.mu.Unlock()
delete(f.clients, userID)
}
// ClearCacheForServer сбрасывает кэш для ВСЕХ пользователей сервера (например, при смене пароля владельцем)
// Это дорогая операция, но необходимая при изменении общих кредов.
func (f *Factory) ClearCacheForServer(serverID uuid.UUID) {
// Пока не реализовано эффективно (нужен обратный индекс).
// Для MVP можно просто очистить весь кэш или оставить как есть,
// так как токены iiko все равно протухнут.
}