From fafa454c24f12ae21856d6b6537ce0e08cad8e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Sun, 18 Jan 2026 21:55:05 +0000 Subject: [PATCH] Delete src/plugins/bad-sandbox.rs --- src/plugins/bad-sandbox.rs | 311 ------------------------------------- 1 file changed, 311 deletions(-) delete mode 100644 src/plugins/bad-sandbox.rs diff --git a/src/plugins/bad-sandbox.rs b/src/plugins/bad-sandbox.rs deleted file mode 100644 index e840c70..0000000 --- a/src/plugins/bad-sandbox.rs +++ /dev/null @@ -1,311 +0,0 @@ -//! Песочница Lua для безопасного выполнения плагинов - -use std::path::Path; -use mlua::{Lua, Value as LuaValue, Result as LuaResult, Error as LuaError}; -use serde_json::{Value, json}; -use uuid::Uuid; - -use crate::plugins::traits::{PluginEvent, PluginHook, PluginState}; -use crate::plugins::channel::PluginInfo; - -/// Песочница Lua для изоляции плагинов -pub struct LuaSandbox { - lua: Lua, - plugin_id: String, - hooks: Vec, -} - -impl LuaSandbox { - /// Создать новую песочницу - pub fn new() -> Result { - let lua = Lua::new(); - - // Настройка безопасного окружения - let globals = lua.globals(); - - // Ограничиваем доступ к опасным функциям - globals.set("os", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict os: {}", e))?; - - globals.set("io", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict io: {}", e))?; - - globals.set("debug", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict debug: {}", e))?; - - globals.set("load", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict load: {}", e))?; - - globals.set("loadfile", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict loadfile: {}", e))?; - - globals.set("dofile", LuaValue::Nil) - .map_err(|e| format!("Failed to restrict dofile: {}", e))?; - - // Добавляем безопасные функции - Self::register_safe_functions(&lua) - .map_err(|e| format!("Failed to register safe functions: {}", e))?; - - Ok(Self { - lua, - plugin_id: String::new(), - hooks: Vec::new(), - }) - } - - /// Зарегистрировать безопасные функции - fn register_safe_functions(lua: &Lua) -> LuaResult<()> { - let globals = lua.globals(); - - // Безопасные функции для логирования - let log_table = lua.create_table()?; - - let lua_clone = lua.clone(); - log_table.set("info", lua.create_function(move |_, msg: String| { - log::info!("[Plugin] {}", msg); - Ok(()) - })?)?; - - let lua_clone = lua.clone(); - log_table.set("error", lua.create_function(move |_, msg: String| { - log::error!("[Plugin] {}", msg); - Ok(()) - })?)?; - - let lua_clone = lua.clone(); - log_table.set("warn", lua.create_function(move |_, msg: String| { - log::warn!("[Plugin] {}", msg); - Ok(()) - })?)?; - - let lua_clone = lua.clone(); - log_table.set("debug", lua.create_function(move |_, msg: String| { - log::debug!("[Plugin] {}", msg); - Ok(()) - })?)?; - - globals.set("log", log_table)?; - - // Функция для работы с JSON - let json_table = lua.create_table()?; - - let lua_clone = lua.clone(); - json_table.set("encode", lua.create_function(move |lua, value: LuaValue| { - let json_value = Self::lua_value_to_json(value)?; - let json_str = serde_json::to_string(&json_value) - .map_err(|e| LuaError::external(e))?; - Ok(json_str) - })?)?; - - let lua_clone = lua.clone(); - json_table.set("decode", lua.create_function(move |lua, json_str: String| { - let json_value: Value = serde_json::from_str(&json_str) - .map_err(|e| LuaError::external(e))?; - Self::json_to_lua_value(lua, json_value) - })?)?; - - globals.set("json", json_table)?; - - // Функция для генерации UUID - let lua_clone = lua.clone(); - globals.set("uuid", lua.create_function(move |_, ()| { - Ok(Uuid::new_v4().to_string()) - })?)?; - - Ok(()) - } - - /// Загрузить плагин из кода - pub fn load_plugin(&mut self, code: &str, path: &str) -> Result { - // Выполняем код плагина - self.lua.load(code).exec() - .map_err(|e| format!("Failed to execute plugin code: {}", e))?; - - // Получаем метаданные плагина - let globals = self.lua.globals(); - - let plugin_table: mlua::Table = globals.get("PLUGIN") - .map_err(|_| "PLUGIN table not found".to_string())?; - - let name: String = plugin_table.get("name") - .map_err(|e| format!("Failed to get plugin name: {}", e))?; - - let version: String = plugin_table.get("version") - .map_err(|e| format!("Failed to get plugin version: {}", e))?; - - let description: String = plugin_table.get("description") - .unwrap_or_else(|_| "No description".to_string()); - - let author: String = plugin_table.get("author") - .unwrap_or_else(|_| "Unknown".to_string()); - - // Генерируем ID плагина - let plugin_id = format!("{}-{}", name, Uuid::new_v4()); - self.plugin_id = plugin_id.clone(); - - // Получаем хуки - let hooks_table: mlua::Table = plugin_table.get("hooks") - .unwrap_or_else(|_| self.lua.create_table().unwrap()); - - let mut hooks = Vec::new(); - - for pair in hooks_table.pairs::() { - match pair { - Ok((hook_name, hook_table)) => { - let function: String = hook_table.get("function") - .unwrap_or_else(|_| hook_name.clone()); - - let priority: u32 = hook_table.get("priority") - .unwrap_or(100); - - let async_hook: bool = hook_table.get("async") - .unwrap_or(false); - - hooks.push(PluginHook { - name: hook_name, - function, - priority, - async_hook, - }); - } - Err(e) => { - log::warn!("Failed to parse hook: {}", e); - } - } - } - - self.hooks = hooks.clone(); - - Ok(PluginInfo { - id: plugin_id, - name, - version, - description, - author, - path: path.to_string(), - state: format!("{:?}", PluginState::Loaded), - hooks, - }) - } - - /// Обработать событие - pub fn handle_event(&self, event: &PluginEvent) -> Result<(), String> { - let globals = self.lua.globals(); - - // Проверяем, есть ли функция для обработки событий - if let Ok(on_event) = globals.get::<_, mlua::Function>("on_event") { - let event_data = json!({ - "type": format!("{:?}", event.event_type), - "data": event.data, - "source": event.source, - "timestamp": event.timestamp, - }); - - let event_json = serde_json::to_string(&event_data) - .map_err(|e| format!("Failed to serialize event: {}", e))?; - - on_event.call::<_, ()>(event_json) - .map_err(|e| format!("Failed to call on_event: {}", e))?; - } - - Ok(()) - } - - /// Выполнить хук - pub fn execute_hook(&self, function_name: &str, data: Value) -> Result { - let globals = self.lua.globals(); - - // Получаем функцию по имени - let hook_func: mlua::Function = globals.get(function_name) - .map_err(|e| format!("Hook function not found: {} - {}", function_name, e))?; - - // Преобразуем данные в Lua значение - let lua_data = Self::json_to_lua_value(&self.lua, data) - .map_err(|e| format!("Failed to convert data to Lua: {}", e))?; - - // Вызываем функцию - let result = hook_func.call::<_, LuaValue>(lua_data) - .map_err(|e| format!("Failed to execute hook: {}", e))?; - - // Преобразуем результат обратно в JSON - Self::lua_value_to_json(result) - .map_err(|e| format!("Failed to convert result to JSON: {}", e)) - } - - /// Преобразовать Lua значение в JSON - fn lua_value_to_json(value: LuaValue) -> Result { - match value { - LuaValue::Nil => Ok(Value::Null), - LuaValue::Boolean(b) => Ok(Value::Bool(b)), - LuaValue::Integer(i) => Ok(Value::Number(i.into())), - LuaValue::Number(n) => { - // Попробуем преобразовать в integer если возможно - if n.fract() == 0.0 { - Ok(Value::Number((n as i64).into())) - } else { - serde_json::Number::from_f64(n) - .map(Value::Number) - .ok_or_else(|| "Invalid number".to_string()) - } - } - LuaValue::String(s) => Ok(Value::String(s.to_string_lossy().to_string())), - LuaValue::Table(table) => { - let mut map = serde_json::Map::new(); - - for pair in table.pairs::() { - match pair { - Ok((key, value)) => { - let key_str = match key { - LuaValue::String(s) => s.to_string_lossy().to_string(), - LuaValue::Integer(i) => i.to_string(), - LuaValue::Number(n) => n.to_string(), - _ => continue, - }; - - let value_json = Self::lua_value_to_json(value)?; - map.insert(key_str, value_json); - } - Err(e) => return Err(format!("Failed to parse table pair: {}", e)), - } - } - - Ok(Value::Object(map)) - } - _ => Err(format!("Unsupported Lua type: {:?}", value.type_name())), - } - } - - /// Преобразовать JSON в Lua значение - fn json_to_lua_value(lua: &Lua, value: Value) -> LuaResult { - match value { - Value::Null => Ok(LuaValue::Nil), - Value::Bool(b) => Ok(LuaValue::Boolean(b)), - Value::Number(n) => { - if let Some(i) = n.as_i64() { - Ok(LuaValue::Integer(i)) - } else if let Some(f) = n.as_f64() { - Ok(LuaValue::Number(f)) - } else { - Err(LuaError::external("Invalid number")) - } - } - Value::String(s) => Ok(LuaValue::String(lua.create_string(&s)?)), - Value::Array(arr) => { - let table = lua.create_table()?; - for (i, item) in arr.into_iter().enumerate() { - let lua_value = Self::json_to_lua_value(lua, item)?; - table.set(i + 1, lua_value)?; - } - Ok(LuaValue::Table(table)) - } - Value::Object(obj) => { - let table = lua.create_table()?; - for (key, value) in obj { - let lua_value = Self::json_to_lua_value(lua, value)?; - table.set(key, lua_value)?; - } - Ok(LuaValue::Table(table)) - } - } - } -}