summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-12-01 20:51:32 +0500
committerilotterytea <iltsu@alright.party>2025-12-01 20:51:32 +0500
commit638622d66dbe58ff96b7d1c2c6ec4b040b27da6d (patch)
tree2f04c3b26a320f4abf5927edc5af34716e42b970
parent0d36a1ee88fb7aedf5b33af7ac95140b002c5a64 (diff)
feat: switch for lua scripts
-rw-r--r--bot/src/commands/lua.hpp62
-rw-r--r--bot/src/config.cpp9
-rw-r--r--bot/src/config.hpp7
-rw-r--r--localization/english.json2
-rw-r--r--localization/russian.json15
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