UNPKG

cs-element

Version:

Advanced reactive data management library with state machines, blueprints, persistence, compression, networking, and multithreading support

543 lines (540 loc) 20.4 kB
'use strict'; // Уровни безопасности var SecurityLevel; (function (SecurityLevel) { SecurityLevel["PUBLIC"] = "public"; SecurityLevel["PROTECTED"] = "protected"; SecurityLevel["PRIVATE"] = "private"; SecurityLevel["CONFIDENTIAL"] = "confidential"; SecurityLevel["TOP_SECRET"] = "top_secret"; })(SecurityLevel || (SecurityLevel = {})); // Типы разрешений var PermissionType; (function (PermissionType) { PermissionType["READ"] = "read"; PermissionType["WRITE"] = "write"; PermissionType["DELETE"] = "delete"; PermissionType["EXECUTE"] = "execute"; PermissionType["ADMIN"] = "admin"; })(PermissionType || (PermissionType = {})); // Методы аутентификации var AuthenticationMethod; (function (AuthenticationMethod) { AuthenticationMethod["PASSWORD"] = "password"; AuthenticationMethod["TOKEN"] = "token"; AuthenticationMethod["CERTIFICATE"] = "certificate"; AuthenticationMethod["BIOMETRIC"] = "biometric"; AuthenticationMethod["MULTI_FACTOR"] = "multi_factor"; })(AuthenticationMethod || (AuthenticationMethod = {})); // Алгоритмы шифрования var EncryptionAlgorithm; (function (EncryptionAlgorithm) { EncryptionAlgorithm["AES_256"] = "aes-256"; EncryptionAlgorithm["RSA_2048"] = "rsa-2048"; EncryptionAlgorithm["ECDSA"] = "ecdsa"; EncryptionAlgorithm["CHACHA20"] = "chacha20"; })(EncryptionAlgorithm || (EncryptionAlgorithm = {})); class SecurityPlugin { /** * Установка ключа шифрования для элемента */ setEncryptionKey(elementId, key) { this._encryptionKeys.set(elementId, key); } /** * Получение ключа шифрования для элемента */ getEncryptionKey(elementId) { return this._encryptionKeys.get(elementId); } constructor(config = {}) { this.name = 'SecurityPlugin'; this.version = '1.0.0'; this.description = 'Плагин для обеспечения безопасности, аутентификации и авторизации'; this.users = new Map(); this.roles = new Map(); this.rules = new Map(); this.sessions = new Map(); this.auditLogs = []; this._encryptionKeys = new Map(); // Для хранения ключей шифрования this.config = { enabled: true, defaultSecurityLevel: SecurityLevel.PROTECTED, encryptionConfig: { algorithm: EncryptionAlgorithm.AES_256, keySize: 256, iterations: 10000 }, sessionTimeout: 3600000, // 1 час maxFailedAttempts: 5, lockoutDuration: 900000, // 15 минут auditingEnabled: true, encryptionEnabled: true, requireAuthentication: false, allowAnonymous: true, ...config }; this.stats = { totalUsers: 0, activeUsers: 0, lockedUsers: 0, totalRoles: 0, totalRules: 0, activeRules: 0, auditLogs: 0, failedAttempts: 0, successfulLogins: 0, deniedOperations: 0, encryptedElements: 0 }; this.initializeDefaultRoles(); } install() { console.log(`Установка ${this.name} v${this.version}`); // Очистка истекших сессий setInterval(() => this.cleanupExpiredSessions(), 60000); // каждую минуту // Очистка старых аудит логов if (this.config.auditingEnabled) { setInterval(() => this.cleanupAuditLogs(), 3600000); // каждый час } } uninstall() { this.sessions.clear(); console.log(`${this.name} деинициализирован`); } getConfig() { return { ...this.config }; } updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } // Lifecycle hooks async beforeCreate(element, context) { if (!this.config.enabled) return { success: true }; const securityContext = this.getSecurityContext(context); const hasPermission = await this.checkPermission(securityContext, PermissionType.WRITE); if (!hasPermission) { this.logAudit(securityContext, 'create_element', 'denied', { elementId: element.id }); return { success: false, error: 'Недостаточно прав для создания элемента', metadata: { securityLevel: this.config.defaultSecurityLevel } }; } // Установка уровня безопасности if (!element.getData('securityLevel')) { element.setData('securityLevel', this.config.defaultSecurityLevel); } this.logAudit(securityContext, 'create_element', 'success', { elementId: element.id }); return { success: true }; } async beforeUpdate(element, context) { if (!this.config.enabled) return { success: true }; const securityContext = this.getSecurityContext(context); const elementSecurityLevel = element.getData('securityLevel') || this.config.defaultSecurityLevel; const hasPermission = await this.checkElementAccess(securityContext, element, PermissionType.WRITE); if (!hasPermission) { this.logAudit(securityContext, 'update_element', 'denied', { elementId: element.id, securityLevel: elementSecurityLevel }); return { success: false, error: 'Недостаточно прав для изменения элемента' }; } this.logAudit(securityContext, 'update_element', 'success', { elementId: element.id }); return { success: true }; } async beforeDelete(element, context) { if (!this.config.enabled) return { success: true }; const securityContext = this.getSecurityContext(context); const hasPermission = await this.checkElementAccess(securityContext, element, PermissionType.DELETE); if (!hasPermission) { this.logAudit(securityContext, 'delete_element', 'denied', { elementId: element.id }); return { success: false, error: 'Недостаточно прав для удаления элемента' }; } this.logAudit(securityContext, 'delete_element', 'success', { elementId: element.id }); return { success: true }; } async afterRead(element, context) { if (!this.config.enabled) return { success: true }; const securityContext = this.getSecurityContext(context); const hasPermission = await this.checkElementAccess(securityContext, element, PermissionType.READ); if (!hasPermission) { this.logAudit(securityContext, 'read_element', 'denied', { elementId: element.id }); return { success: false, error: 'Недостаточно прав для чтения элемента' }; } // Расшифровка данных если необходимо if (this.config.encryptionEnabled) { await this.decryptElementData(element, securityContext); } this.logAudit(securityContext, 'read_element', 'success', { elementId: element.id }); return { success: true }; } // Управление пользователями createUser(userData) { const user = { id: this.generateId(), failedAttempts: 0, isActive: true, ...userData }; this.users.set(user.id, user); this.updateStats(); return user; } getUser(id) { return this.users.get(id); } getUserByUsername(username) { for (const user of this.users.values()) { if (user.username === username) { return user; } } return undefined; } updateUser(id, updates) { const user = this.users.get(id); if (!user) return false; Object.assign(user, updates); this.updateStats(); return true; } deleteUser(id) { const deleted = this.users.delete(id); if (deleted) this.updateStats(); return deleted; } // Управление ролями createRole(roleData) { const role = { id: this.generateId(), ...roleData }; this.roles.set(role.id, role); this.updateStats(); return role; } getRole(id) { return this.roles.get(id); } updateRole(id, updates) { const role = this.roles.get(id); if (!role) return false; Object.assign(role, updates); this.updateStats(); return true; } deleteRole(id) { const deleted = this.roles.delete(id); if (deleted) this.updateStats(); return deleted; } // Управление правилами безопасности addSecurityRule(ruleData) { const rule = { id: this.generateId(), createdAt: new Date(), updatedAt: new Date(), ...ruleData }; this.rules.set(rule.id, rule); this.updateStats(); return rule; } getSecurityRule(id) { return this.rules.get(id); } updateSecurityRule(id, updates) { const rule = this.rules.get(id); if (!rule) return false; Object.assign(rule, { ...updates, updatedAt: new Date() }); this.updateStats(); return true; } deleteSecurityRule(id) { const deleted = this.rules.delete(id); if (deleted) this.updateStats(); return deleted; } // Аутентификация и авторизация async authenticate(username, password, _method = AuthenticationMethod.PASSWORD) { const user = this.getUserByUsername(username); if (!user || !user.isActive) { this.stats.failedAttempts++; return null; } // Проверка блокировки if (user.lockedUntil && user.lockedUntil > new Date()) { return null; } // Проверка пароля const isValidPassword = await this.verifyPassword(password, user); if (!isValidPassword) { user.failedAttempts++; this.stats.failedAttempts++; // Блокировка при превышении попыток if (user.failedAttempts >= this.config.maxFailedAttempts) { user.lockedUntil = new Date(Date.now() + this.config.lockoutDuration); this.updateStats(); } return null; } // Успешная аутентификация user.failedAttempts = 0; user.lastLogin = new Date(); user.lockedUntil = undefined; const sessionId = this.generateSessionId(); const session = { user, sessionId, timestamp: new Date(), operation: 'login' }; this.sessions.set(sessionId, session); this.stats.successfulLogins++; this.updateStats(); return sessionId; } logout(sessionId) { return this.sessions.delete(sessionId); } getSession(sessionId) { const session = this.sessions.get(sessionId); if (!session) return undefined; // Проверка истечения сессии if (Date.now() - session.timestamp.getTime() > this.config.sessionTimeout) { this.sessions.delete(sessionId); return undefined; } return session; } async checkPermission(context, permission) { if (!this.config.requireAuthentication && this.config.allowAnonymous) { return true; } if (!context.user) { return false; } const user = context.user; // Проверка прямых разрешений пользователя if (user.permissions.includes(permission) || user.permissions.includes(PermissionType.ADMIN)) { return true; } // Проверка разрешений через роли for (const roleId of user.roles) { const role = this.roles.get(roleId); if (role && role.isActive && (role.permissions.includes(permission) || role.permissions.includes(PermissionType.ADMIN))) { return true; } } return false; } async checkElementAccess(context, element, permission) { const hasBasePermission = await this.checkPermission(context, permission); if (!hasBasePermission) { return false; } const elementSecurityLevel = element.getData('securityLevel') || this.config.defaultSecurityLevel; const userSecurityLevel = context.user?.securityLevel || SecurityLevel.PUBLIC; return this.compareSecurityLevels(userSecurityLevel, elementSecurityLevel); } async encryptElementData(element, _context) { try { const data = element.serialize(); const encryptedData = await this.encrypt(JSON.stringify(data)); element.setData('_encrypted', true); element.setData('_encryptedData', encryptedData); this.stats.encryptedElements++; return true; } catch (error) { console.error('Ошибка шифрования данных элемента:', error); return false; } } async decryptElementData(element, _context) { try { if (!element.getData('_encrypted')) { return true; // Данные не зашифрованы } const encryptedData = element.getData('_encryptedData'); if (!encryptedData) { return false; } const decryptedData = await this.decrypt(encryptedData); const data = JSON.parse(decryptedData); // Восстановление данных Object.keys(data).forEach(key => { if (key !== '_encrypted' && key !== '_encryptedData') { element.setData(key, data[key]); } }); element.deleteData('_encrypted'); element.deleteData('_encryptedData'); return true; } catch (error) { console.error('Ошибка расшифровки данных элемента:', error); return false; } } // Аудит logAudit(context, operation, result, details) { if (!this.config.auditingEnabled) return; const auditLog = { id: this.generateId(), timestamp: new Date(), user: context.user?.username, operation, resource: context.resource, result, details, securityLevel: context.user?.securityLevel || SecurityLevel.PUBLIC, ipAddress: context.ipAddress, userAgent: context.userAgent }; this.auditLogs.push(auditLog); this.stats.auditLogs++; if (result === 'denied') { this.stats.deniedOperations++; } } getAuditLogs(filter) { if (!filter) return [...this.auditLogs]; return this.auditLogs.filter(log => { return Object.entries(filter).every(([key, value]) => { return log[key] === value; }); }); } getSecurityContext(context) { return { user: context?.user, sessionId: context?.sessionId, ipAddress: context?.ipAddress, userAgent: context?.userAgent, timestamp: new Date(), operation: context?.operation || 'unknown', resource: context?.resource, metadata: context?.metadata }; } compareSecurityLevels(userLevel, requiredLevel) { const levels = [ SecurityLevel.PUBLIC, SecurityLevel.PROTECTED, SecurityLevel.PRIVATE, SecurityLevel.CONFIDENTIAL, SecurityLevel.TOP_SECRET ]; const userLevelIndex = levels.indexOf(userLevel); const requiredLevelIndex = levels.indexOf(requiredLevel); return userLevelIndex >= requiredLevelIndex; } async verifyPassword(password, _user) { // Простая проверка пароля (в реальном приложении должен быть хеш) return password.length >= 8; // Минимальная проверка } async encrypt(data) { // Простое шифрование для демонстрации return Buffer.from(data).toString('base64'); } async decrypt(encryptedData) { // Простая расшифровка для демонстрации return Buffer.from(encryptedData, 'base64').toString(); } initializeDefaultRoles() { // Создание базовых ролей this.createRole({ name: 'admin', description: 'Администратор системы', permissions: [PermissionType.ADMIN], securityLevel: SecurityLevel.TOP_SECRET, isActive: true }); this.createRole({ name: 'user', description: 'Обычный пользователь', permissions: [PermissionType.READ, PermissionType.WRITE], securityLevel: SecurityLevel.PROTECTED, isActive: true }); this.createRole({ name: 'guest', description: 'Гостевой доступ', permissions: [PermissionType.READ], securityLevel: SecurityLevel.PUBLIC, isActive: true }); } cleanupExpiredSessions() { const now = Date.now(); for (const [sessionId, session] of this.sessions.entries()) { if (now - session.timestamp.getTime() > this.config.sessionTimeout) { this.sessions.delete(sessionId); } } this.updateStats(); } cleanupAuditLogs() { // Удаление логов старше 30 дней const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000); this.auditLogs = this.auditLogs.filter(log => log.timestamp.getTime() > thirtyDaysAgo); this.stats.auditLogs = this.auditLogs.length; this.stats.lastAuditCleanup = new Date(); } updateStats() { this.stats.totalUsers = this.users.size; this.stats.activeUsers = Array.from(this.users.values()).filter(u => u.isActive).length; this.stats.lockedUsers = Array.from(this.users.values()).filter(u => u.lockedUntil && u.lockedUntil > new Date()).length; this.stats.totalRoles = this.roles.size; this.stats.totalRules = this.rules.size; this.stats.activeRules = Array.from(this.rules.values()).filter(r => r.enabled).length; } generateId() { return Math.random().toString(36).substr(2, 9); } generateSessionId() { return Math.random().toString(36).substr(2, 16) + Date.now().toString(36); } // Публичные методы для получения статистики и данных getStats() { return { ...this.stats }; } getAllUsers() { return Array.from(this.users.values()); } getAllRoles() { return Array.from(this.roles.values()); } getAllSecurityRules() { return Array.from(this.rules.values()); } getActiveSessions() { return Array.from(this.sessions.values()); } } exports.SecurityPlugin = SecurityPlugin; //# sourceMappingURL=security.js.map