Resolve all high-severity architecture review findings

This commit is contained in:
Joseph Doherty
2026-09-09 16:13:58 -04:00
parent 8bfe65512e
commit 146a13238f
192 changed files with 3160 additions and 753 deletions
@@ -1,3 +1,7 @@
@using Microsoft.Extensions.DependencyInjection
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@inject IServiceProvider MutationServices
@page "/deployment/instances/{Id:int}/configure"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances
@@ -5,14 +9,12 @@
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@using ZB.MOM.WW.ScadaBridge.Commons.Types
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@using ZB.MOM.WW.ScadaBridge.TemplateEngine.Flattening
@using ZB.MOM.WW.ScadaBridge.TemplateEngine.Services
@using ZB.MOM.WW.ScadaBridge.DeploymentManager
@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Dialogs
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDeployment)]
@inject ITemplateEngineRepository TemplateEngineRepository
@@ -963,8 +965,14 @@
// CentralUI-024: delegates to the shared helper so the claim type stays
// resolved through JwtTokenService rather than a duplicated magic string.
private Task<string> GetCurrentUserAsync()
=> AuthStateProvider.GetCurrentUsernameAsync();
private async Task<string> GetCurrentUserAsync()
{
var user = await AuthStateProvider.RequireRoleAsync(ZB.MOM.WW.ScadaBridge.Security.Roles.Deployer);
var current = await TemplateEngineRepository.GetInstanceByIdAsync(Id);
if (current is null || !await SiteScope.IsSiteAllowedAsync(current.SiteId))
throw new UnauthorizedAccessException("The instance is outside your current site scope.");
return user;
}
// ── Bindings ────────────────────────────────────────────
@@ -1243,7 +1251,7 @@
_bindingOverrides.GetValueOrDefault(kv.Key)))
.ToList();
var user = await GetCurrentUserAsync();
var result = await InstanceService.SetConnectionBindingsAsync(Id, bindings, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.SetConnectionBindingsAsync(Id, bindings, currentUser));
if (result.IsSuccess)
{
SnapshotSavedBindingState();
@@ -1323,8 +1331,7 @@
{
if (_existingOverrides.TryGetValue(attrName, out var ovr))
{
await TemplateEngineRepository.DeleteInstanceAttributeOverrideAsync(ovr.Id);
await TemplateEngineRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(new DeleteInstanceAttributeOverrideCommand(Id, attrName));
_existingOverrides.Remove(attrName);
}
_overrideValues.Remove(attrName);
@@ -1377,7 +1384,7 @@
var failures = new List<string>();
foreach (var (attrName, value) in toSave)
{
var result = await InstanceService.SetAttributeOverrideAsync(Id, attrName, value, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.SetAttributeOverrideAsync(Id, attrName, value, currentUser));
if (result.IsSuccess)
_existingOverrides[attrName] = result.Value!;
else
@@ -1454,7 +1461,7 @@
var failures = new List<string>();
foreach (var (attrName, value) in outcome.Overrides)
{
var result = await InstanceService.SetAttributeOverrideAsync(Id, attrName, value, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.SetAttributeOverrideAsync(Id, attrName, value, currentUser));
if (result.IsSuccess)
{
_existingOverrides[attrName] = result.Value!;
@@ -1622,7 +1629,7 @@
{
if (_existingAlarmOverrides.ContainsKey(alarmName))
{
var del = await InstanceService.DeleteAlarmOverrideAsync(Id, alarmName, user);
var del = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.DeleteAlarmOverrideAsync(Id, alarmName, currentUser));
if (!del.IsSuccess)
{
_editingError = del.Error;
@@ -1639,8 +1646,8 @@
}
else
{
var result = await InstanceService.SetAlarmOverrideAsync(
Id, alarmName, overrideJson, priority, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.SetAlarmOverrideAsync(
Id, alarmName, overrideJson, priority, currentUser));
if (!result.IsSuccess)
{
_editingError = result.Error;
@@ -1675,7 +1682,7 @@
try
{
var user = await GetCurrentUserAsync();
var result = await InstanceService.DeleteAlarmOverrideAsync(Id, alarmName, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.DeleteAlarmOverrideAsync(Id, alarmName, currentUser));
if (result.IsSuccess)
{
_existingAlarmOverrides.Remove(alarmName);
@@ -1718,7 +1725,6 @@
}
await UpsertNativeOverrideCore(sourceName, conn, sref, filt);
await TemplateEngineRepository.SaveChangesAsync();
_toast.ShowSuccess($"Saved native alarm source override on '{sourceName}'.");
}
catch (Exception ex)
@@ -1751,27 +1757,8 @@
/// </summary>
private async Task UpsertNativeOverrideCore(string sourceName, string? conn, string? sref, string? filt)
{
var existing = await TemplateEngineRepository.GetNativeAlarmSourceOverrideAsync(Id, sourceName);
if (existing == null)
{
var ovr = new InstanceNativeAlarmSourceOverride(sourceName)
{
InstanceId = Id,
ConnectionNameOverride = conn,
SourceReferenceOverride = sref,
ConditionFilterOverride = filt
};
await TemplateEngineRepository.AddInstanceNativeAlarmSourceOverrideAsync(ovr);
_existingNativeOverrides[sourceName] = ovr;
}
else
{
existing.ConnectionNameOverride = conn;
existing.SourceReferenceOverride = sref;
existing.ConditionFilterOverride = filt;
await TemplateEngineRepository.UpdateInstanceNativeAlarmSourceOverrideAsync(existing);
_existingNativeOverrides[sourceName] = existing;
}
var result = await MutationServices.ExecuteConfigurationAsync(new SetInstanceNativeAlarmSourceOverrideCommand(Id, sourceName, conn, sref, filt));
if (result is InstanceNativeAlarmSourceOverride saved) _existingNativeOverrides[sourceName] = saved;
// Keep the inline editor showing what was just persisted.
_nasConnEdit[sourceName] = conn;
@@ -1781,12 +1768,7 @@
private async Task ClearNativeOverrideCore(string sourceName)
{
var existing = await TemplateEngineRepository.GetNativeAlarmSourceOverrideAsync(Id, sourceName);
if (existing != null)
{
await TemplateEngineRepository.DeleteInstanceNativeAlarmSourceOverrideAsync(existing.Id);
await TemplateEngineRepository.SaveChangesAsync();
}
await MutationServices.ExecuteConfigurationAsync(new DeleteInstanceNativeAlarmSourceOverrideCommand(Id, sourceName));
_existingNativeOverrides.Remove(sourceName);
_nasConnEdit[sourceName] = null;
_nasRefEdit[sourceName] = null;
@@ -1849,17 +1831,9 @@
return;
}
// Every row was validated up front, so the batch applies as a unit through
// the same repository upsert/clear the inline editor uses.
foreach (var row in outcome.Rows)
{
if (row.IsClear)
await ClearNativeOverrideCore(row.SourceName);
else
await UpsertNativeOverrideCore(
row.SourceName, row.Connection, row.SourceReference, row.Filter);
}
await TemplateEngineRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(new SetInstanceNativeAlarmSourceOverridesCommand(Id,
outcome.Rows.Select(row => new NativeAlarmSourceOverrideEntry(row.SourceName, row.Connection, row.SourceReference, row.Filter)).ToList()));
await OnInitializedAsync();
_nasCsvImportSucceeded = true;
_nasCsvImportResult = $"Imported {outcome.Rows.Count} native alarm source override(s).";
@@ -1957,7 +1931,7 @@
try
{
var user = await GetCurrentUserAsync();
var result = await InstanceService.AssignToAreaAsync(Id, _reassignAreaId == 0 ? null : _reassignAreaId, user);
var result = await MutationServices.GetRequiredService<ConfigurationCommandService>().ExecuteInstanceAsync(Id, null, (instanceService, currentUser) => instanceService.AssignToAreaAsync(Id, _reassignAreaId == 0 ? null : _reassignAreaId, currentUser));
if (result.IsSuccess)
{
_areaName = _siteAreas.FirstOrDefault(a => a.Id == _reassignAreaId)?.Name ?? "";