mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-05-15 07:54:08 +00:00
making the audit fully automatic
This commit is contained in:
parent
054481abcf
commit
820c9e2596
@ -1,4 +1,5 @@
|
||||
using AIStudio.Components;
|
||||
using AIStudio.Agents.AssistantAudit;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
using AIStudio.Tools.PluginSystem.Assistants;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@ -7,22 +8,85 @@ namespace AIStudio.Pages;
|
||||
|
||||
public partial class Assistants : MSGComponentBase
|
||||
{
|
||||
private bool isAutoAuditing;
|
||||
|
||||
[Inject]
|
||||
private AssistantPluginAuditService AssistantPluginAuditService { get; init; } = null!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED, Event.PLUGINS_RELOADED ]);
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
await this.TryAutoAuditAssistantsAsync();
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<PluginAssistants> AssistantPlugins =>
|
||||
PluginFactory.RunningPlugins.OfType<PluginAssistants>()
|
||||
.Where(plugin => this.SettingsManager.IsPluginEnabled(plugin))
|
||||
.ToList();
|
||||
|
||||
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
private async Task TryAutoAuditAssistantsAsync()
|
||||
{
|
||||
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
|
||||
return this.InvokeAsync(this.StateHasChanged);
|
||||
if (this.isAutoAuditing || !this.SettingsManager.ConfigurationData.AssistantPluginAudit.AutomaticallyAuditAssistants)
|
||||
return;
|
||||
|
||||
return Task.CompletedTask;
|
||||
this.isAutoAuditing = true;
|
||||
|
||||
try
|
||||
{
|
||||
var wasConfigurationChanged = false;
|
||||
var assistantPlugins = PluginFactory.RunningPlugins.OfType<PluginAssistants>().ToList();
|
||||
foreach (var assistantPlugin in assistantPlugins)
|
||||
{
|
||||
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
||||
if (!securityState.RequiresAudit)
|
||||
continue;
|
||||
|
||||
var audit = await this.AssistantPluginAuditService.RunAuditAsync(assistantPlugin);
|
||||
if (audit.Level is AssistantAuditLevel.UNKNOWN)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.SettingsSuggest, string.Format(this.T("The automatic security audit for the assistant plugin '{0}' failed. Please run it manually from the plugins page."), assistantPlugin.Name)));
|
||||
continue;
|
||||
}
|
||||
|
||||
this.UpsertAuditCard(audit);
|
||||
wasConfigurationChanged = true;
|
||||
}
|
||||
|
||||
if (!wasConfigurationChanged)
|
||||
return;
|
||||
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.isAutoAuditing = false;
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpsertAuditCard(PluginAssistantAudit audit)
|
||||
{
|
||||
var audits = this.SettingsManager.ConfigurationData.AssistantPluginAudits;
|
||||
var existingIndex = audits.FindIndex(x => x.PluginId == audit.PluginId);
|
||||
if (existingIndex >= 0)
|
||||
audits[existingIndex] = audit;
|
||||
else
|
||||
audits.Add(audit);
|
||||
}
|
||||
|
||||
protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
{
|
||||
if (triggeredEvent is Event.PLUGINS_RELOADED)
|
||||
await this.TryAutoAuditAssistantsAsync();
|
||||
|
||||
if (triggeredEvent is Event.CONFIGURATION_CHANGED or Event.PLUGINS_RELOADED)
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ public partial class Plugins : MSGComponentBase
|
||||
private const string GROUP_ENABLED = "Enabled";
|
||||
private const string GROUP_DISABLED = "Disabled";
|
||||
private const string GROUP_INTERNAL = "Internal";
|
||||
private bool isAutoAuditing;
|
||||
|
||||
private DataAssistantPluginAudit AssistantPluginAuditSettings => this.SettingsManager.ConfigurationData.AssistantPluginAudit;
|
||||
|
||||
@ -50,6 +51,12 @@ public partial class Plugins : MSGComponentBase
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
await this.TryAutoAuditAssistantsAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private async Task PluginActivationStateChanged(IPluginMetadata pluginMeta)
|
||||
@ -75,31 +82,6 @@ public partial class Plugins : MSGComponentBase
|
||||
return;
|
||||
|
||||
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
||||
if (securityState.RequiresAudit)
|
||||
{
|
||||
if (this.AssistantPluginAuditSettings.AutomaticallyAuditAssistants)
|
||||
{
|
||||
var audit = await this.AssistantPluginAuditService.RunAuditAsync(assistantPlugin);
|
||||
if (audit.Level is AssistantAuditLevel.UNKNOWN)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.SettingsSuggest, string.Format(T("The Security Audit returned an invalid result, please try again manually."))));
|
||||
await this.OpenAssistantAuditDialogAsync(pluginMeta.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
this.UpsertAuditCard(audit);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
|
||||
securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
||||
}
|
||||
else
|
||||
{
|
||||
await this.OpenAssistantAuditDialogAsync(pluginMeta.Id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (securityState.RequiresAudit)
|
||||
{
|
||||
await this.OpenAssistantAuditDialogAsync(pluginMeta.Id);
|
||||
@ -204,6 +186,47 @@ public partial class Plugins : MSGComponentBase
|
||||
|
||||
private PluginAssistants? TryGetAssistantPlugin(Guid pluginId) => PluginFactory.RunningPlugins.OfType<PluginAssistants>().FirstOrDefault(x => x.Id == pluginId);
|
||||
|
||||
private async Task TryAutoAuditAssistantsAsync()
|
||||
{
|
||||
if (this.isAutoAuditing || !this.AssistantPluginAuditSettings.AutomaticallyAuditAssistants)
|
||||
return;
|
||||
|
||||
this.isAutoAuditing = true;
|
||||
|
||||
try
|
||||
{
|
||||
var wasConfigurationChanged = false;
|
||||
var assistantPlugins = PluginFactory.RunningPlugins.OfType<PluginAssistants>().ToList();
|
||||
foreach (var assistantPlugin in assistantPlugins)
|
||||
{
|
||||
var securityState = PluginAssistantSecurityResolver.Resolve(this.SettingsManager, assistantPlugin);
|
||||
if (!securityState.RequiresAudit)
|
||||
continue;
|
||||
|
||||
var audit = await this.AssistantPluginAuditService.RunAuditAsync(assistantPlugin);
|
||||
if (audit.Level is AssistantAuditLevel.UNKNOWN)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.SettingsSuggest, string.Format(this.T("The automatic security audit for the assistant plugin '{0}' failed. Please run it manually."), assistantPlugin.Name)));
|
||||
continue;
|
||||
}
|
||||
|
||||
this.UpsertAuditCard(audit);
|
||||
wasConfigurationChanged = true;
|
||||
}
|
||||
|
||||
if (!wasConfigurationChanged)
|
||||
return;
|
||||
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.isAutoAuditing = false;
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpsertAuditCard(PluginAssistantAudit audit)
|
||||
{
|
||||
var audits = this.SettingsManager.ConfigurationData.AssistantPluginAudits;
|
||||
@ -220,7 +243,12 @@ public partial class Plugins : MSGComponentBase
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.PLUGINS_RELOADED or Event.CONFIGURATION_CHANGED:
|
||||
case Event.PLUGINS_RELOADED:
|
||||
await this.TryAutoAuditAssistantsAsync();
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
break;
|
||||
|
||||
case Event.CONFIGURATION_CHANGED:
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -181,8 +181,8 @@ public static class PluginAssistantSecurityResolver
|
||||
BadgeIcon = GetSecurityBadgeIcon(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlockedByMinimum, canOverride),
|
||||
Headline = isBlockedByMinimum ? TB("This assistant is currently locked.") : TB("This assistant can still be used because your settings allow it."),
|
||||
Description = isBlockedByMinimum
|
||||
? string.Format(TB("The current audit result \"{0}\" is below your required minimum level \"{1}\". Your security settings therefore block this assistant plugin."), auditLevel.GetName(), auditSettings.MinimumLevel.GetName())
|
||||
: string.Format(TB("The current audit result is \"{0}\", which is below your required minimum level \"{1}\". Your settings still allow manual activation, but the assistant keeps this security status and should be reviewed carefully."), auditLevel.GetName(), auditSettings.MinimumLevel.GetName()),
|
||||
? string.Format(TB("The current audit result '{0}' is below your required minimum level '{1}'. Your security settings therefore block this assistant plugin."), auditLevel.GetName(), auditSettings.MinimumLevel.GetName())
|
||||
: string.Format(TB("The current audit result is '{0}', which is below your required minimum level '{1}'. Your settings still allow manual activation, but the assistant keeps this security status and should be reviewed carefully."), auditLevel.GetName(), auditSettings.MinimumLevel.GetName()),
|
||||
StatusColor = GetAvailabilityColor(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlockedByMinimum, canOverride),
|
||||
StatusIcon = GetAvailabilityIcon(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlockedByMinimum, canOverride),
|
||||
ActionLabel = TB("Open Security Check"),
|
||||
@ -215,7 +215,7 @@ public static class PluginAssistantSecurityResolver
|
||||
StatusLabel = GetAvailabilityLabel(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlocked: false, canOverride: false),
|
||||
BadgeIcon = GetSecurityBadgeIcon(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlocked: false, canOverride: false),
|
||||
Headline = TB("This assistant is currently unlocked."),
|
||||
Description = string.Format(TB("The stored audit matches the current plugin code and meets your required minimum level \"{0}\"."), auditSettings.MinimumLevel.GetName()),
|
||||
Description = string.Format(TB("The stored audit matches the current plugin code and meets your required minimum level '{0}'."), auditSettings.MinimumLevel.GetName()),
|
||||
StatusColor = GetAvailabilityColor(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlocked: false, canOverride: false),
|
||||
StatusIcon = GetAvailabilityIcon(requiresAudit: false, hasAudit, hasHashMismatch: false, isBlocked: false, canOverride: false),
|
||||
ActionLabel = TB("Open Security Check"),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user