mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-09-13 03:10:37 +00:00
Fixed loading Lua modules of a plugin during its validation
This commit is contained in:
parent
f0c35d8914
commit
4a8190240e
@ -385,7 +385,15 @@ public static partial class PluginFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<PluginBase> Load(string? pluginPath, string code, CancellationToken cancellationToken = default)
|
/// <param name="pluginPath">The directory the plugin is located in, or null when the code has no directory yet.</param>
|
||||||
|
/// <param name="code">The Lua code of the plugin's main file.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token for running the Lua code.</param>
|
||||||
|
/// <param name="allowedBaseDirectory">
|
||||||
|
/// The directory the plugin path must be nested in. Without it, the installed plugins directory
|
||||||
|
/// is used. Validating a plugin before its installation needs this, because the plugin lives in
|
||||||
|
/// a staging directory at that point and could not load any of its own Lua modules otherwise.
|
||||||
|
/// </param>
|
||||||
|
public static async Task<PluginBase> Load(string? pluginPath, string code, CancellationToken cancellationToken = default, string? allowedBaseDirectory = null)
|
||||||
{
|
{
|
||||||
if(ForbiddenPlugins.Check(code) is { IsForbidden: true } forbiddenState)
|
if(ForbiddenPlugins.Check(code) is { IsForbidden: true } forbiddenState)
|
||||||
return new NoPlugin($"This plugin is forbidden: {forbiddenState.Message}");
|
return new NoPlugin($"This plugin is forbidden: {forbiddenState.Message}");
|
||||||
@ -394,7 +402,7 @@ public static partial class PluginFactory
|
|||||||
if (!string.IsNullOrWhiteSpace(pluginPath))
|
if (!string.IsNullOrWhiteSpace(pluginPath))
|
||||||
{
|
{
|
||||||
// Add the module loader so that the plugin can load other Lua modules:
|
// Add the module loader so that the plugin can load other Lua modules:
|
||||||
state.ModuleLoader = new PluginLoader(pluginPath);
|
state.ModuleLoader = new PluginLoader(pluginPath, allowedBaseDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add some useful libraries:
|
// Add some useful libraries:
|
||||||
|
|||||||
@ -14,10 +14,17 @@ namespace AIStudio.Tools.PluginSystem;
|
|||||||
/// Loading other modules outside the plugin directory is not allowed.
|
/// Loading other modules outside the plugin directory is not allowed.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="pluginDirectory">The directory where the plugin is located.</param>
|
/// <param name="pluginDirectory">The directory where the plugin is located.</param>
|
||||||
public sealed class PluginLoader(string pluginDirectory) : ILuaModuleLoader
|
/// <param name="allowedBaseDirectory">
|
||||||
|
/// The directory the plugin directory must be nested in. Without it, the installed plugins directory
|
||||||
|
/// is used. Validating a plugin before its installation needs this, because the plugin is not
|
||||||
|
/// installed yet and lives in a staging directory outside the installed plugins directory.
|
||||||
|
/// </param>
|
||||||
|
public sealed class PluginLoader(string pluginDirectory, string? allowedBaseDirectory = null) : ILuaModuleLoader
|
||||||
{
|
{
|
||||||
private static readonly string PLUGIN_BASE_PATH = Path.Join(SettingsManager.DataDirectory, "plugins");
|
private static readonly string PLUGIN_BASE_PATH = Path.Join(SettingsManager.DataDirectory, "plugins");
|
||||||
|
|
||||||
|
private readonly string baseDirectory = string.IsNullOrWhiteSpace(allowedBaseDirectory) ? PLUGIN_BASE_PATH : allowedBaseDirectory;
|
||||||
|
|
||||||
#region Implementation of ILuaModuleLoader
|
#region Implementation of ILuaModuleLoader
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -27,8 +34,8 @@ public sealed class PluginLoader(string pluginDirectory) : ILuaModuleLoader
|
|||||||
if (moduleName.Contains("..") || pluginDirectory.Contains(".."))
|
if (moduleName.Contains("..") || pluginDirectory.Contains(".."))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Ensure that the plugin directory is nested in the plugin base path:
|
// Ensure that the plugin directory is nested in the allowed base directory:
|
||||||
if (!pluginDirectory.StartsWith(PLUGIN_BASE_PATH, StringComparison.OrdinalIgnoreCase))
|
if (!pluginDirectory.StartsWith(this.baseDirectory, StringComparison.OrdinalIgnoreCase))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var path = Path.Join(pluginDirectory, $"{moduleName}.lua");
|
var path = Path.Join(pluginDirectory, $"{moduleName}.lua");
|
||||||
|
|||||||
@ -572,7 +572,10 @@ public sealed class AssistantPluginInstallService
|
|||||||
private static async Task<AssistantPluginValidationResult> ValidateAssistantPluginCodeAsync(string pluginDirectory, string pluginCode,
|
private static async Task<AssistantPluginValidationResult> ValidateAssistantPluginCodeAsync(string pluginDirectory, string pluginCode,
|
||||||
string notAssistantIssue, string invalidAssistantIssue, string internalPluginIdIssue, CancellationToken token)
|
string notAssistantIssue, string invalidAssistantIssue, string internalPluginIdIssue, CancellationToken token)
|
||||||
{
|
{
|
||||||
var plugin = await PluginFactory.Load(pluginDirectory, pluginCode, token);
|
// The plugin is not installed yet: it sits in a staging directory outside the installed
|
||||||
|
// plugins directory. We allow that directory as the module base, so the plugin can load its
|
||||||
|
// own Lua modules, e.g., an icon.lua, while we validate it:
|
||||||
|
var plugin = await PluginFactory.Load(pluginDirectory, pluginCode, token, pluginDirectory);
|
||||||
if (plugin is not PluginAssistants assistantPlugin)
|
if (plugin is not PluginAssistants assistantPlugin)
|
||||||
return AssistantPluginValidationResult.Failure(string.Format(notAssistantIssue, string.Join("; ", plugin.Issues)));
|
return AssistantPluginValidationResult.Failure(string.Format(notAssistantIssue, string.Join("; ", plugin.Issues)));
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user