refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)

Solution + 23 src projects + 26 test projects renamed; folders, csproj,
namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated.
ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated.
SQL roles/logins, LDAP domains, CLI command name, and CLI config dir
(~/.scadalink → ~/.scadabridge) also renamed.

Build green; 5 Host.Tests fail awaiting SQL login rename in next commit.
Pre-existing StaleTagMonitor timing flakes unchanged.

Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
Joseph Doherty
2026-05-28 09:37:45 -04:00
parent 6d87ee3c3b
commit 7b0b9c7365
1531 changed files with 11180 additions and 11054 deletions
+17 -17
View File
@@ -2,7 +2,7 @@
| Field | Value |
|-------|-------|
| Module | `src/ScadaLink.Transport` |
| Module | `src/ZB.MOM.WW.ScadaBridge.Transport` |
| Design doc | `docs/requirements/Component-Transport.md` |
| Status | Reviewed |
| Last reviewed | 2026-05-28 |
@@ -54,7 +54,7 @@ entry-count / per-entry decompression cap).
| Severity | High |
| Category | Correctness & logic bugs |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:844-851` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:844-851` |
**Resolution** — Extended `ApplyTemplatesAsync`'s Overwrite branch with three
new private diff-and-merge helpers (`SyncTemplateAttributesAsync`,
@@ -101,7 +101,7 @@ template whose Scripts / Attributes / Alarms differ.
| Severity | High |
| Category | Correctness & logic bugs |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:1213-1221` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:1213-1221` |
**Resolution** — Added a private `SyncExternalSystemMethodsAsync` helper to
`BundleImporter` modeled on the T-001 `SyncTemplate*Async` helpers (dictionary-
@@ -137,7 +137,7 @@ methods differ.
| Severity | High |
| Category | Security |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:184-203`, `src/ScadaLink.CentralUI/Components/Pages/Design/TransportImport.razor.cs:267-309`, `src/ScadaLink.Commons/Types/Transport/BundleSession.cs:14-16` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:184-203`, `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TransportImport.razor.cs:267-309`, `src/ZB.MOM.WW.ScadaBridge.Commons/Types/Transport/BundleSession.cs:14-16` |
**Description**
@@ -174,7 +174,7 @@ _Unresolved._
| Severity | Medium |
| Category | Security |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/TransportOptions.cs:12`, `docs/requirements/Component-Transport.md` §11 |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/TransportOptions.cs:12`, `docs/requirements/Component-Transport.md` §11 |
**Resolution (2026-05-28):** Added a new `BundleUnlockRateLimiter` class (in-memory, per-key sliding-window counter via `ConcurrentDictionary<string, Queue<DateTimeOffset>>` with per-bucket locking), registered as a singleton in `AddTransport`, and wired into `BundleImporter.LoadAsync` before the decrypt attempt — exceeding the per-window cap throws the new `BundleUnlockRateLimitedException` (429-equivalent). The importer keys the limiter on the bundle's `ContentHash` (it has no `IHttpContext` dependency by design); an IP-aware caller can use the limiter's public `TryRegisterAttempt(clientIp, max)` directly for true per-IP keying. `BundleUnlockRateLimiterTests` covers: N attempts allowed and N+1 rejected; full-window expiry releases the entire budget; partial expiry releases only the aged-out slots (sliding window); per-key isolation; argument validation.
@@ -208,12 +208,12 @@ _Unresolved._
| Severity | Medium |
| Category | Security |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Encryption/BundleSecretEncryptor.cs:31-49`, `src/ScadaLink.Transport/Serialization/ManifestValidator.cs:29-53` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Encryption/BundleSecretEncryptor.cs:31-49`, `src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/ManifestValidator.cs:29-53` |
**Description**
AES-GCM is called with no Associated Authenticated Data (AAD). The `manifest`
fields — `SourceEnvironment`, `ExportedBy`, `ScadaLinkVersion`, `Summary`,
fields — `SourceEnvironment`, `ExportedBy`, `ScadaBridgeVersion`, `Summary`,
`Contents`, `CreatedAtUtc`, etc. — are plaintext and only the `ContentHash`
field is checked against the content bytes. An attacker who obtains a bundle
can edit any non-`ContentHash` manifest field (e.g. rewrite the
@@ -244,7 +244,7 @@ _Unresolved._
| Severity | Medium |
| Category | Security |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Serialization/BundleSerializer.cs:121-156`, `src/ScadaLink.Transport/Import/BundleImporter.cs:132-143` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Serialization/BundleSerializer.cs:121-156`, `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:132-143` |
**Description**
@@ -277,7 +277,7 @@ _Unresolved._
| Severity | Medium |
| Category | Performance & resource management |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:614-696`, `src/ScadaLink.Transport/Import/BundleSessionStore.cs:67-93` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:614-696`, `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleSessionStore.cs:67-93` |
**Description**
@@ -313,7 +313,7 @@ _Unresolved._
| Severity | Low |
| Category | Performance & resource management |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:252-272` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:252-272` |
**Resolution (2026-05-28):** Added a bulk `GetTemplatesWithChildrenAsync(IEnumerable<string> names, CancellationToken)` method on `ITemplateEngineRepository` and implemented it on `TemplateEngineRepository` with a single `Where(t => names.Contains(t.Name))` + `Include(Attributes/Alarms/Scripts/Compositions).AsSplitQuery()` round-trip; null / empty / duplicate names are filtered before the IN clause. `BundleImporter.PreviewAsync` now calls the bulk method once with `content.Templates.Select(t => t.Name)` and indexes the result by name, replacing the previous `GetAllTemplatesAsync` scan + per-match `GetTemplateWithChildrenAsync(stub.Id)` round-trip pair. Regression tests: `TemplateEngineRepositoryTests.GetTemplatesWithChildrenAsync_*` (4 tests — bulk fetch, empty input, null enumerable, dedup) and `BundleImporterPreviewTests.PreviewAsync_multiple_templates_with_children_diffs_each_correctly` (asserts the bulk fetch hydrates all three templates' Attributes / Alarms / Scripts so the diff classifies each as Identical).
@@ -346,7 +346,7 @@ _Unresolved._
| Severity | Low |
| Category | Concurrency & thread safety |
| Status | Resolved |
| Location | `src/ScadaLink.Transport/Import/BundleImporter.cs:528, 668, 703`, `src/ScadaLink.ConfigurationDatabase/Services/AuditCorrelationContext.cs` |
| Location | `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:528, 668, 703`, `src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Services/AuditCorrelationContext.cs` |
**Resolution (2026-05-28):**
Took option (a). `AuditCorrelationContext` now backs `BundleImportId` with a `static AsyncLocal<Guid?>`,
@@ -389,14 +389,14 @@ _Unresolved._
| Severity | Medium |
| Category | Testing coverage |
| Status | Resolved |
| Location | `tests/ScadaLink.Transport.IntegrationTests/ConflictResolutionTests.cs`, `tests/ScadaLink.Transport.IntegrationTests/Import/BundleImporterApplyTests.cs` |
| Location | `tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/ConflictResolutionTests.cs`, `tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/BundleImporterApplyTests.cs` |
**Resolution (2026-05-28):** Re-verified the listed gaps against the current
tree. Each item the finding enumerated has landed in the recent fix commits:
- **Template Overwrite with divergent Attributes / Alarms / Scripts** — covered
by `ApplyAsync_Overwrite_synchronises_attributes_alarms_and_scripts_to_bundle`
in `tests/ScadaLink.Transport.IntegrationTests/Import/BundleImporterApplyTests.cs`
in `tests/ZB.MOM.WW.ScadaBridge.Transport.IntegrationTests/Import/BundleImporterApplyTests.cs`
(added with the Transport-001 fix in commit `e3ca9af`). Asserts the bundle's
child collections fully replace the divergent target shape AND that per-field
audit rows (`TemplateAttributeAdded`/`Updated`/`Deleted`, the alarm and script
@@ -406,10 +406,10 @@ tree. Each item the finding enumerated has landed in the recent fix commits:
same file (Transport-002 fix, commit `e3ca9af`). Mirrors the T-001 shape with
`ExternalSystemMethodAdded`/`Updated`/`Deleted` audit rows.
- **Per-IP unlock-throttle behaviour (Transport-004)** — covered by
`tests/ScadaLink.Transport.Tests/Import/BundleUnlockRateLimiterTests.cs` (12
`tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleUnlockRateLimiterTests.cs` (12
tests: under-limit, at-limit rejection, sliding-window reset, per-key isolation).
- **Failed-apply session retention (Transport-007)** — covered by
`tests/ScadaLink.Transport.Tests/Import/BundleSessionStoreTests.cs`:
`tests/ZB.MOM.WW.ScadaBridge.Transport.Tests/Import/BundleSessionStoreTests.cs`:
`Get_after_TTL_returns_null_and_evicts`, `EvictExpired_removes_all_past_ttl`,
`UnlockFailures_ExpireOnTtlAndGetReturnsZero`, and
`UnlockFailures_EvictExpired_ClearsStaleEntries` collectively pin the TTL
@@ -460,7 +460,7 @@ Add the missing integration tests above. Most can be modelled after
| Severity | Low |
| Category | Documentation & comments |
| Status | Resolved |
| Location | `docs/requirements/Component-Transport.md` Import Flow Step 1, `src/ScadaLink.Transport/Import/BundleImporter.cs:124-203` |
| Location | `docs/requirements/Component-Transport.md` Import Flow Step 1, `src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleImporter.cs:124-203` |
**Description**
@@ -500,7 +500,7 @@ bundle prompt is surfaced AFTER the manifest+hash check, and that a dedicated
| Severity | Low |
| Category | Documentation & comments |
| Status | Resolved |
| Location | `docs/requirements/Component-Transport.md` §Audit Trail, `src/ScadaLink.ConfigurationDatabase/Repositories/CentralUiRepository.cs:148` |
| Location | `docs/requirements/Component-Transport.md` §Audit Trail, `src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Repositories/CentralUiRepository.cs:148` |
**Description**