Resolve all high-severity architecture review findings
This commit is contained in:
+27
-53
@@ -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 ?? "";
|
||||
|
||||
Reference in New Issue
Block a user