mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Add a basic permission system based on lua stdlib loading
This commit is contained in:
parent
5191f4c9eb
commit
1cc849b9f7
3 changed files with 71 additions and 3 deletions
|
@ -73,19 +73,52 @@ bool PluginController::tryLoadFromDir(const QDir &pluginDir)
|
||||||
this->load(index, pluginDir, PluginMeta(doc.object()));
|
this->load(index, pluginDir, PluginMeta(doc.object()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void PluginController::openLibrariesFor(lua_State *L, PluginMeta meta)
|
||||||
|
{
|
||||||
|
// copied from linit.c
|
||||||
|
static const std::array<luaL_Reg, 11> loadedlibs = {
|
||||||
|
luaL_Reg{LUA_GNAME, luaopen_base},
|
||||||
|
luaL_Reg{LUA_LOADLIBNAME, luaopen_package},
|
||||||
|
luaL_Reg{LUA_COLIBNAME, luaopen_coroutine},
|
||||||
|
luaL_Reg{LUA_TABLIBNAME, luaopen_table},
|
||||||
|
luaL_Reg{LUA_IOLIBNAME, luaopen_io},
|
||||||
|
luaL_Reg{LUA_OSLIBNAME, luaopen_os},
|
||||||
|
luaL_Reg{LUA_STRLIBNAME, luaopen_string},
|
||||||
|
luaL_Reg{LUA_MATHLIBNAME, luaopen_math},
|
||||||
|
luaL_Reg{LUA_UTF8LIBNAME, luaopen_utf8},
|
||||||
|
luaL_Reg{LUA_DBLIBNAME, luaopen_debug},
|
||||||
|
luaL_Reg{NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto ® : loadedlibs)
|
||||||
|
{
|
||||||
|
if (meta.libraryPermissions.contains(QString(reg.name)))
|
||||||
|
{
|
||||||
|
luaL_requiref(L, reg.name, reg.func, int(true));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PluginController::load(QFileInfo index, QDir pluginDir, PluginMeta meta)
|
void PluginController::load(QFileInfo index, QDir pluginDir, PluginMeta meta)
|
||||||
{
|
{
|
||||||
qCDebug(chatterinoLua) << "Running lua file" << index;
|
qCDebug(chatterinoLua) << "Running lua file" << index;
|
||||||
lua_State *l = luaL_newstate();
|
lua_State *l = luaL_newstate();
|
||||||
luaL_openlibs(l);
|
this->openLibrariesFor(l, meta);
|
||||||
this->loadChatterinoLib(l);
|
this->loadChatterinoLib(l);
|
||||||
|
|
||||||
auto pluginName = pluginDir.dirName();
|
auto pluginName = pluginDir.dirName();
|
||||||
auto plugin = std::make_unique<Plugin>(pluginName, l, meta, pluginDir);
|
auto plugin = std::make_unique<Plugin>(pluginName, l, meta, pluginDir);
|
||||||
this->plugins_.insert({pluginName, std::move(plugin)});
|
this->plugins_.insert({pluginName, std::move(plugin)});
|
||||||
|
|
||||||
luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
int err = luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
qCWarning(chatterinoLua)
|
||||||
|
<< "Failed to load" << pluginName << "plugin from" << index << ": "
|
||||||
|
<< lua::humanErrorText(l, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ struct PluginMeta {
|
||||||
QString homepage;
|
QString homepage;
|
||||||
std::vector<QString> tags;
|
std::vector<QString> tags;
|
||||||
|
|
||||||
|
std::set<QString> libraryPermissions;
|
||||||
|
|
||||||
explicit PluginMeta(const QJsonObject &obj)
|
explicit PluginMeta(const QJsonObject &obj)
|
||||||
: name(obj.value("name").toString())
|
: name(obj.value("name").toString())
|
||||||
, description(obj.value("description").toString())
|
, description(obj.value("description").toString())
|
||||||
|
@ -37,7 +39,11 @@ struct PluginMeta {
|
||||||
{
|
{
|
||||||
for (const auto &t : obj.value("tags").toArray())
|
for (const auto &t : obj.value("tags").toArray())
|
||||||
{
|
{
|
||||||
tags.push_back(t.toString());
|
this->tags.push_back(t.toString());
|
||||||
|
}
|
||||||
|
for (const auto &t : obj.value("library_permissions").toArray())
|
||||||
|
{
|
||||||
|
this->libraryPermissions.insert(t.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -121,6 +127,9 @@ public:
|
||||||
private:
|
private:
|
||||||
void load(QFileInfo index, QDir pluginDir, PluginMeta meta);
|
void load(QFileInfo index, QDir pluginDir, PluginMeta meta);
|
||||||
void loadChatterinoLib(lua_State *l);
|
void loadChatterinoLib(lua_State *l);
|
||||||
|
|
||||||
|
// This function adds lua standard libraries into the state
|
||||||
|
void openLibrariesFor(lua_State *L, PluginMeta meta);
|
||||||
bool tryLoadFromDir(const QDir &pluginDir);
|
bool tryLoadFromDir(const QDir &pluginDir);
|
||||||
std::map<QString, std::unique_ptr<Plugin>> plugins_;
|
std::map<QString, std::unique_ptr<Plugin>> plugins_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,6 +49,32 @@ PluginsPage::PluginsPage()
|
||||||
|
|
||||||
pl->addRow("Homepage", homepage);
|
pl->addRow("Homepage", homepage);
|
||||||
|
|
||||||
|
QString libString;
|
||||||
|
bool hasDangerous = false;
|
||||||
|
for (const auto &library : plugin->meta.libraryPermissions)
|
||||||
|
{
|
||||||
|
if (!libString.isEmpty())
|
||||||
|
{
|
||||||
|
libString += ", ";
|
||||||
|
}
|
||||||
|
if (library == "os" || library == "io")
|
||||||
|
{
|
||||||
|
hasDangerous = true;
|
||||||
|
}
|
||||||
|
libString += library;
|
||||||
|
}
|
||||||
|
if (hasDangerous)
|
||||||
|
{
|
||||||
|
libString += "\nDetected potentially dangerous libraries used, be "
|
||||||
|
"careful with this plugin";
|
||||||
|
}
|
||||||
|
auto *libs = new QLabel(libString);
|
||||||
|
if (hasDangerous)
|
||||||
|
{
|
||||||
|
libs->setStyleSheet("color: red");
|
||||||
|
}
|
||||||
|
pl->addRow("Used libraries", libs);
|
||||||
|
|
||||||
auto *reload = new QPushButton("Reload");
|
auto *reload = new QPushButton("Reload");
|
||||||
QObject::connect(reload, &QPushButton::pressed, [name = codename]() {
|
QObject::connect(reload, &QPushButton::pressed, [name = codename]() {
|
||||||
getApp()->plugins->reload(name);
|
getApp()->plugins->reload(name);
|
||||||
|
|
Loading…
Reference in a new issue