diff options
| author | ilotterytea <iltsu@alright.party> | 2025-12-01 20:51:32 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-12-01 20:51:32 +0500 |
| commit | 638622d66dbe58ff96b7d1c2c6ec4b040b27da6d (patch) | |
| tree | 2f04c3b26a320f4abf5927edc5af34716e42b970 | |
| parent | 0d36a1ee88fb7aedf5b33af7ac95140b002c5a64 (diff) | |
feat: switch for lua scripts
| -rw-r--r-- | bot/src/commands/lua.hpp | 62 | ||||
| -rw-r--r-- | bot/src/config.cpp | 9 | ||||
| -rw-r--r-- | bot/src/config.hpp | 7 | ||||
| -rw-r--r-- | localization/english.json | 2 | ||||
| -rw-r--r-- | localization/russian.json | 15 |
5 files changed, 58 insertions, 37 deletions
diff --git a/bot/src/commands/lua.hpp b/bot/src/commands/lua.hpp index 27cc142..2f236f2 100644 --- a/bot/src/commands/lua.hpp +++ b/bot/src/commands/lua.hpp @@ -1,5 +1,6 @@ #pragma once +#include <algorithm> #include <memory> #include <optional> #include <sol/sol.hpp> @@ -18,52 +19,52 @@ #include "schemas/user.hpp" #include "utils/string.hpp" -void print_lua_object_type(const sol::object &obj); +void print_lua_object_type(const sol::object& obj); namespace bot::command::lua { namespace library { void add_bot_library(std::shared_ptr<sol::state> state); void add_bot_library(std::shared_ptr<sol::state> state, - const InstanceBundle &bundle); + const InstanceBundle& bundle); void add_time_library(std::shared_ptr<sol::state> state); void add_json_library(std::shared_ptr<sol::state> state); void add_twitch_library(std::shared_ptr<sol::state> state, - const Request &request, - const InstanceBundle &bundle); + const Request& request, + const InstanceBundle& bundle); void add_kick_library(std::shared_ptr<sol::state> state, - const InstanceBundle &bundle); + const InstanceBundle& bundle); void add_net_library(std::shared_ptr<sol::state> state); void add_db_library(std::shared_ptr<sol::state> state, - const Configuration &config); + const Configuration& config); void add_irc_library(std::shared_ptr<sol::state> state, - const InstanceBundle &bundle); + const InstanceBundle& bundle); void add_l10n_library(std::shared_ptr<sol::state> state, - const InstanceBundle &bundle); + const InstanceBundle& bundle); void add_storage_library(std::shared_ptr<sol::state> state, - const Request &request, const Configuration &cfg, - const std::string &lua_id); + const Request& request, const Configuration& cfg, + const std::string& lua_id); void add_rss_library(std::shared_ptr<sol::state> state); void add_base_libraries(std::shared_ptr<sol::state> state); void add_chat_libraries(std::shared_ptr<sol::state> state, - const Request &request, - const InstanceBundle &bundle); + const Request& request, + const InstanceBundle& bundle); } - command::Response run_safe_lua_script(const Request &request, - const InstanceBundle &bundle, - const std::string &script, + command::Response run_safe_lua_script(const Request& request, + const InstanceBundle& bundle, + const std::string& script, std::string lua_id = ""); class LuaCommand : public Command { public: LuaCommand(std::shared_ptr<sol::state> luaState, - const std::string &content); + const std::string& content); ~LuaCommand() = default; - Response run(const InstanceBundle &bundle, - const Request &request) const override; + Response run(const InstanceBundle& bundle, + const Request& request) const override; std::string get_name() const override { return this->name; } int get_delay_seconds() const override { return this->delay; } @@ -94,8 +95,13 @@ namespace bot::command::lua { int get_delay_seconds() const override { return 1; } - command::Response run(const InstanceBundle &bundle, - const command::Request &request) const override { + command::Response run(const InstanceBundle& bundle, + const command::Request& request) const override { + if (!bundle.configuration.lua.allow_arbitrary_scripts) { + throw ResponseException<ResponseError::ILLEGAL_COMMAND>( + request, bundle.localization); + } + if (!request.message.has_value()) { throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( request, bundle.localization, command::CommandArgument::VALUE); @@ -112,13 +118,23 @@ namespace bot::command::lua { int get_delay_seconds() const override { return 2; } - command::Response run(const InstanceBundle &bundle, - const command::Request &request) const override { + command::Response run(const InstanceBundle& bundle, + const command::Request& request) const override { if (!request.message.has_value()) { throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>( request, bundle.localization, command::CommandArgument::VALUE); } + if (!bundle.configuration.lua.allow_arbitrary_scripts && + !std::any_of(bundle.configuration.lua.script_whitelist.begin(), + bundle.configuration.lua.script_whitelist.end(), + [&request](const std::string& i) { + return i == request.message.value(); + })) { + throw ResponseException<ResponseError::ILLEGAL_COMMAND>( + request, bundle.localization); + } + std::vector<std::string> parts = utils::string::split_text(request.message.value(), ' '); @@ -154,7 +170,7 @@ namespace bot::command::lua { std::string contentType = response.header["Content-Type"]; if (!std::any_of( mimeTypes.begin(), mimeTypes.end(), - [&contentType](const auto &x) { return x == contentType; })) { + [&contentType](const auto& x) { return x == contentType; })) { throw ResponseException<ResponseError::INCORRECT_ARGUMENT>( request, bundle.localization, url); } diff --git a/bot/src/config.cpp b/bot/src/config.cpp index 6cd8cf1..ccb042a 100644 --- a/bot/src/config.cpp +++ b/bot/src/config.cpp @@ -7,6 +7,7 @@ #include <string> #include "logger.hpp" +#include "utils/string.hpp" namespace bot { sol::table Configuration::as_lua_table( @@ -98,6 +99,7 @@ namespace bot { UrlConfiguration url_cfg; TokenConfiguration token_cfg; RssConfiguration rss_cfg; + LuaConfiguration lua_cfg; std::string line; while (std::getline(ifs, line, '\n')) { @@ -168,6 +170,12 @@ namespace bot { rss_cfg.bridge = value; } + else if (key == "lua.allow_arbitrary_scripts") { + lua_cfg.allow_arbitrary_scripts = std::stoi(value); + } else if (key == "lua.script_whitelist") { + lua_cfg.script_whitelist = utils::string::split_text(value, ','); + } + else if (key == "token.github") { token_cfg.github_token = value; } @@ -181,6 +189,7 @@ namespace bot { cfg.database = db_cfg; cfg.tokens = token_cfg; cfg.rss = rss_cfg; + cfg.lua = lua_cfg; log::info("Configuration", "Successfully loaded the file from '" + file_path + "'"); diff --git a/bot/src/config.hpp b/bot/src/config.hpp index 1a09463..70491bd 100644 --- a/bot/src/config.hpp +++ b/bot/src/config.hpp @@ -3,6 +3,7 @@ #include <optional> #include <sol/sol.hpp> #include <string> +#include <vector> #define GET_DATABASE_CONNECTION_URL(c) \ "dbname = " + c.database.name + " user = " + c.database.user + \ @@ -63,6 +64,11 @@ namespace bot { int timeout = 60; }; + struct LuaConfiguration { + bool allow_arbitrary_scripts = false; + std::vector<std::string> script_whitelist; + }; + struct Configuration { TwitchCredentialsConfiguration twitch_credentials; KickCredentialsConfiguration kick_credentials; @@ -72,6 +78,7 @@ namespace bot { UrlConfiguration url; TokenConfiguration tokens; RssConfiguration rss; + LuaConfiguration lua; sol::table as_lua_table(std::shared_ptr<sol::state> luaState) const; }; diff --git a/localization/english.json b/localization/english.json index c471ada..b9673ad 100644 --- a/localization/english.json +++ b/localization/english.json @@ -18,7 +18,7 @@ "error.something_went_wrong": "Something went wrong", "error.external_api_error": "External API error (%s%s)", "error.insufficient_rights": "Insufficient rights", - "error.illegal_command": "Command not available", + "error.illegal_command": "You are not authorized to use this command. This incident will be reported.", "error.lua_execution_error": "Lua execution error: %s", "ping.response": "{sender.alias_name}: funnywhitecat Pong! %s Uptime: %s · Used memory: %sMB", diff --git a/localization/russian.json b/localization/russian.json index 4be5345..67a2207 100644 --- a/localization/russian.json +++ b/localization/russian.json @@ -1,6 +1,5 @@ { "msg.owner": "Свяжитесь с @%s", - "argument.subcommand": "Подкоманда", "argument.message": "Сообщение", "argument.interval": "Интервал", @@ -8,7 +7,6 @@ "argument.target": "Цель", "argument.value": "Значение", "argument.amount": "Количество", - "error.template": "{sender.alias_name}: 🚨 %s", "error.not_enough_arguments": "Недостаточно аргументов (%s)", "error.incorrect_argument": "Некорректный аргумент (%s)", @@ -18,36 +16,27 @@ "error.something_went_wrong": "Что-то пошло не так", "error.external_api_error": "Ошибка стороннего API (%s%s)", "error.insufficient_rights": "Недостаточно прав", - "error.illegal_command": "Команда недоступна", + "error.illegal_command": "Вы неавторизованы для использования данной команды. Об этом инциденте будет сообщено.", "error.lua_execution_error": "Lua execution error: %s", - "ping.response": "{sender.alias_name}: funnywhitecat Понг! %s Время сессии: %s · ОЗУ: %sМБ", - "event.on": "{sender.alias_name}: Событие \"%s\" успешно создано!", "event.off": "{sender.alias_name}: Событие \"%s\" удалено!", - "notify.sub": "{sender.alias_name}: Вы успешно подписались на событие \"%s\"!", "notify.unsub": "{sender.alias_name}: Вы отписались от события \"%s\"!", - "join.response": "{sender.alias_name}: Успешно зашёл в ваш чат!", "join.response_in_chat": "Привет! Я - %s и я буду обслуживать этот чат. Напишите {default.prefix}help, чтобы узнать о командах!", "join.already_in": "{sender.alias_name}: Уже в вашем чат!", "join.rejoined": "{sender.alias_name}: Перезашёл в ваш чат!", "join.from_other_chat": "{sender.alias_name}: Чтобы бот мог зайти в ваш чат, нужно написать {default.prefix}join непосредственно в чате %s", "join.not_allowed": "{sender.alias_name}: Бот не может заходить в чужие чаты!%s", - "custom_command.new": "{sender.alias_name}: Новая команда \"%s\" была успешно создана!", "custom_command.delete": "{sender.alias_name}: Команда \"%s\" была удалена!", - "timer.new": "{sender.alias_name}: Новый таймер \"%s\" был успешно создан!", "timer.delete": "{sender.alias_name}: Таймер \"%s\" был удален!", - "help.response": "{sender.alias_name}: Справочник по командам бота: %s", - "chatters.response": "{sender.alias_name}: Список чаттеров: %s", - "set.locale": "{sender.alias_name}: Теперь бот говорит по-русски в этом чате!", "set.prefix": "{sender.alias_name}: Префикс бота был установлен как \"%s\"", "set.feature.disabled": "{sender.alias_name}: Функция \"%s\" была выключена в этом чате!", "set.feature.enabled": "{sender.alias_name}: Функция \"%s\" была включена в этом чате!" -} +}
\ No newline at end of file |
