Treat a failed security check as no check at all

This commit is contained in:
Thorsten Sommer 2026-09-19 20:35:06 +02:00
parent 018f8c9701
commit c48ec58080
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108

View File

@ -74,11 +74,26 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
private bool CanRunAudit => this.plugin is not null && this.EffectiveProvider != AIStudio.Settings.Provider.NONE && !this.isAuditing && !this.securityState.IsEnterpriseApproved;
private bool IsAuditBelowMinimum => this.audit is not null && this.audit.Level < this.MinimumLevel;
/// <summary>
/// The audit result this dialog acts on: the one it has, unless that one concluded nothing.
/// </summary>
/// <remarks>
/// UNKNOWN is not a low audit level, it is the absence of a result: the model was unreachable,
/// the key was wrong, no provider was trusted enough. Everything which decides something has to
/// read it as no audit at all -- whether the plugin may be activated, and what this dialog hands
/// back to be stored. Otherwise a check which failed would unlock a plugin nobody has checked,
/// and storing it would replace the last result which did say something, because audits are kept
/// one per plugin. This is the rule PluginAssistantSecurityResolver already applies to the stored
/// audits. What the dialog shows the user still reads the raw result: a failed run is precisely
/// what they need to see.
/// </remarks>
private PluginAssistantAudit? ConclusiveAudit => this.audit is { Level: not AssistantAuditLevel.UNKNOWN } ? this.audit : null;
private bool IsActivationBlockedBySettings => this.AuditSettings.RequireAuditBeforeActivation && (this.audit is null || this.IsAuditBelowMinimum && this.AuditSettings.BlockActivationBelowMinimum);
private bool IsAuditBelowMinimum => this.ConclusiveAudit is not null && this.ConclusiveAudit.Level < this.MinimumLevel;
private bool RequiresActivationConfirmation => this.audit is not null && this.IsAuditBelowMinimum && !this.IsActivationBlockedBySettings;
private bool IsActivationBlockedBySettings => this.AuditSettings.RequireAuditBeforeActivation && (this.ConclusiveAudit is null || this.IsAuditBelowMinimum && this.AuditSettings.BlockActivationBelowMinimum);
private bool RequiresActivationConfirmation => this.ConclusiveAudit is not null && this.IsAuditBelowMinimum && !this.IsActivationBlockedBySettings;
private bool CanEnablePlugin => this.plugin is not null && !this.isAuditing && !this.IsActivationBlockedBySettings;
@ -88,10 +103,9 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
/// Whether this dialog has produced an audit result, which is why it offers no second run.
/// </summary>
/// <remarks>
/// Set only for a result worth keeping. An audit which ended in UNKNOWN answered nothing about
/// the plugin: the model was unreachable, the key was wrong, no provider was trusted enough.
/// Locking the button on that would leave the user in front of a plugin they cannot check and
/// cannot enable, with closing and reopening the dialog as the only way on.
/// A run which concluded nothing must not set this. It would leave the user in front of a plugin
/// they cannot check and cannot enable, with closing and reopening the dialog as the only way on
/// -- and a failed run is the one case where trying again is exactly the right thing to do.
/// </remarks>
private bool justAudited;
@ -139,7 +153,7 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
finally
{
this.isAuditing = false;
this.justAudited = this.audit is { Level: not AssistantAuditLevel.UNKNOWN };
this.justAudited = this.ConclusiveAudit is not null;
await this.InvokeAsync(this.StateHasChanged);
}
}
@ -154,13 +168,13 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
private void CloseWithoutActivation()
{
if (this.audit is null)
if (this.ConclusiveAudit is null)
{
this.MudDialog.Cancel();
return;
}
this.MudDialog.Close(DialogResult.Ok(new AssistantPluginAuditDialogResult(this.audit, false)));
this.MudDialog.Close(DialogResult.Ok(new AssistantPluginAuditDialogResult(this.ConclusiveAudit, false)));
}
private async Task EnablePlugin()
@ -174,7 +188,7 @@ public partial class AssistantPluginAuditDialog : MSGComponentBase
if (this.RequiresActivationConfirmation && !await this.ConfirmActivationBelowMinimumAsync())
return;
this.MudDialog.Close(DialogResult.Ok(new AssistantPluginAuditDialogResult(this.audit, true)));
this.MudDialog.Close(DialogResult.Ok(new AssistantPluginAuditDialogResult(this.ConclusiveAudit, true)));
}
private async Task<bool> ConfirmActivationBelowMinimumAsync()