Add multi-site support to the CMS 13 solution#363
Merged
Conversation
… a Normal host name.
…rited behaviour is required
… as it only works for the old model.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds multi-site (application + host context) support across the CMS 13 Stott Security solution so security configuration can be viewed/edited/exported per selected context, including inheritance/override behavior.
Changes:
- Introduces UI context selection/switching and wires
appId/hostNamethrough CSP/Permission Policy/Tools/Preview flows. - Updates Optimizely backend services/repositories/controllers to support context-aware CRUD, fallback chains, and override create/delete endpoints.
- Expands caching/auditing/routing to include context (cache keys, route data), and updates tests/sample app configuration accordingly.
Reviewed changes
Copilot reviewed 145 out of 150 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Stott.Security.Ui/src/index.css | Widen vertical tab to accommodate new UI. |
| src/Stott.Security.Ui/src/Tools/ImportSettings.jsx | Adds context selection to import flow; sends context via query params. |
| src/Stott.Security.Ui/src/Tools/ExportSettings.jsx | Adds modal + context selection for exports; sends context via query params. |
| src/Stott.Security.Ui/src/Preview/HeaderPreview.jsx | Adds context switcher and context-aware preview requests. |
| src/Stott.Security.Ui/src/PermissionsPolicy/PermissionsPolicyContainer.jsx | Adds context switching + inherited/override UX for Permission Policy directives. |
| src/Stott.Security.Ui/src/PermissionsPolicy/PermissionPolicySettings.jsx | Makes settings context-aware and disables edits when inherited. |
| src/Stott.Security.Ui/src/PermissionsPolicy/PermissionPolicyCard.jsx | Hides editing when inherited; passes context to editor. |
| src/Stott.Security.Ui/src/PermissionsPolicy/EditPermissionPolicy.jsx | Sends context in save payload; refreshes directives by context. |
| src/Stott.Security.Ui/src/CustomHeaders/CustomHeaderModal.jsx | Sends context in custom header save payload. |
| src/Stott.Security.Ui/src/CustomHeaders/CustomHeaderCard.jsx | Hides edit/delete actions when inherited. |
| src/Stott.Security.Ui/src/Context/StottSecurityContext.jsx | Makes Permission Policy data fetch/save context-aware; adds override operations. |
| src/Stott.Security.Ui/src/Common/ContextSwitcher.jsx | New: modal-based context switcher (applications + hosts). |
| src/Stott.Security.Ui/src/Common/ContextSelector.jsx | New: dropdown context selector for modals (import/export). |
| src/Stott.Security.Ui/src/CSP/ViolationReport.jsx | Context-aware CSP violation queries + pass context to conversion actions. |
| src/Stott.Security.Ui/src/CSP/SandboxSettings.jsx | Context-aware sandbox CRUD + inherited/override UX. |
| src/Stott.Security.Ui/src/CSP/PermissionModal.jsx | Sends context when saving CSP permissions. |
| src/Stott.Security.Ui/src/CSP/PermissionList.jsx | Context-aware list + shows inherited sources via a separate endpoint. |
| src/Stott.Security.Ui/src/CSP/InheritedPermission.jsx | New: renders inherited CSP permissions row. |
| src/Stott.Security.Ui/src/CSP/EditSettings.jsx | Context-aware CSP settings CRUD + inherited/override UX. |
| src/Stott.Security.Ui/src/CSP/EditPermission.jsx | Refactors directives rendering via shared table; passes context to modal. |
| src/Stott.Security.Ui/src/CSP/DirectivesTable.jsx | New: shared directive description table for CSP sources. |
| src/Stott.Security.Ui/src/CSP/CspContainer.jsx | New: CSP area consolidated into a tabbed container with context switcher. |
| src/Stott.Security.Ui/src/CSP/ConvertCspViolation.jsx | Sends context when appending permission from violation. |
| src/Stott.Security.Ui/src/CSP/AddPermission.jsx | Passes context into create permission modal. |
| src/Stott.Security.Ui/src/App.jsx | Consolidates CSP routes into a single “Content Security Policy” entry w/ tab selection. |
| src/Stott.Security.Ui/.env.production | Adds new context/override endpoints + inherited list/delete endpoints. |
| src/Stott.Security.Ui/.env | Adds new context/override endpoints + inherited list/delete endpoints. |
| src/Stott.Security.Optimizely/MigrationSteps/SetUpDefaultSourcesMigrationStep.cs | Removed legacy migration step. |
| src/Stott.Security.Optimizely/MigrationSteps/NonceMigrationStep.cs | Removed legacy nonce migration step. |
| src/Stott.Security.Optimizely/Features/Tools/PermissionPolicyModel.cs | Tools export model adjustments (now includes directives list directly). |
| src/Stott.Security.Optimizely/Features/Tools/MigrationService.cs | Export/import now support app/host context and include context on CSP sources. |
| src/Stott.Security.Optimizely/Features/Tools/MigrationController.cs | Adds context params to tools import/export; sanitizes host input. |
| src/Stott.Security.Optimizely/Features/Tools/IMigrationService.cs | Interface updated for context-aware export/import. |
| src/Stott.Security.Optimizely/Features/Tools/IMigrationRepository.cs | Interface updated for context-aware import persistence. |
| src/Stott.Security.Optimizely/Features/Tools/CspSourceModel.cs | Adds AppId/HostName to exported CSP sources. |
| src/Stott.Security.Optimizely/Features/SecurityTxt/SecurityTxtHelpers.cs | Host summaries enriched (type/language) and filters redirect hosts. |
| src/Stott.Security.Optimizely/Features/Route/SecurityRouteHelper.cs | Route data now includes app + host context; async API; preview query context support. |
| src/Stott.Security.Optimizely/Features/Route/SecurityRouteData.cs | Adds AppId/HostName fields. |
| src/Stott.Security.Optimizely/Features/Route/ISecurityRouteHelper.cs | Changes helper API to async. |
| src/Stott.Security.Optimizely/Features/Preview/CompiledHeaderController.cs | Updates to async route helper API. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Service/IPermissionPolicyService.cs | Adds context-aware operations + override lifecycle methods. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Repository/PermissionPolicyMapper.cs | Adds context to mappings; entity creation now accepts app/host. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Repository/IPermissionPolicyRepository.cs | Adds context-aware CRUD + override operations. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/PermissionPolicyController.cs | Adds context query params, override endpoints, and inheritance response. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Models/SavePermissionPolicyModel.cs | Adds AppId/HostName to save model. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Models/PermissionPolicySettingsModel.cs | Adds AppId/HostName to settings model. |
| src/Stott.Security.Optimizely/Features/PermissionPolicy/Models/IPermissionPolicySettings.cs | Interface expanded with AppId/HostName. |
| src/Stott.Security.Optimizely/Features/Middleware/SecurityHeaderMiddleware.cs | Uses async route data to compile headers. |
| src/Stott.Security.Optimizely/Features/Header/HeaderCompilationService.cs | Cache keys now include context; nonce substitution now async; compiled headers are context-aware. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/Service/ICustomHeaderService.cs | Context-aware listing/compilation + override lifecycle + context-scoped save. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/Service/CustomHeaderService.cs | Implements context-aware caches and override operations. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/Repository/ICustomHeaderRepository.cs | Context-aware queries + override create/delete contract. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/Repository/CustomHeaderRepository.cs | Implements context fallback chain + override create/delete. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/Models/SaveCustomHeaderModel.cs | Adds context fields; duplicate validation now scoped to context. |
| src/Stott.Security.Optimizely/Features/CustomHeaders/CustomHeaderController.cs | Context-aware listing and override endpoints; sanitizes host input. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/Service/ICspSettingsService.cs | Context-aware get/save/delete + exists-for-context checks. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/Service/CspSettingsService.cs | Implements context-aware caching + delete + exists checks. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/Repository/ICspSettingsRepository.cs | Context-aware get/save/delete + exact-context fetch. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/Repository/CspSettingsRepository.cs | Implements fallback selection + context-scoped save/delete. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/CspSettingsResponseModel.cs | New: response DTO includes IsInherited. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/CspSettingsModel.cs | Adds AppId/HostName to save model. |
| src/Stott.Security.Optimizely/Features/Csp/Settings/CspSettingsController.cs | Context-aware get/save/delete + IsInherited reporting; sanitizes host input. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/Service/ICspSandboxService.cs | Context-aware get/save/delete + exists-for-context checks. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/Service/CspSandboxService.cs | Implements context-aware caching + delete + exists checks. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/SandboxResponseModel.cs | New: response DTO includes IsInherited. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/SandboxModel.cs | Adds context fields and implements sandbox settings interface. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/Repository/ICspSandboxRepository.cs | Context-aware get/save/delete + exact-context fetch. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/Repository/CspSandboxRepository.cs | Implements fallback selection + context-scoped save/delete. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/ISandboxSettings.cs | New: interface for sandbox settings mapping. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/CspSandboxMapper.cs | Moves/expands mapper to support interface and response mapping with inheritance. |
| src/Stott.Security.Optimizely/Features/Csp/Sandbox/CspSandboxController.cs | Context-aware get/save/delete + IsInherited reporting; sanitizes host input. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/ViolationReportSummary.cs | Adds AppId/HostName to report summary. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/Service/ICspViolationReportService.cs | Context-aware save/list. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/Service/CspViolationReportService.cs | Passes context through to repository. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/Repository/ICspViolationReportRepository.cs | Context-aware save/list. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/Repository/CspViolationReportRepository.cs | Stores and queries violations by context; groups include context fields. |
| src/Stott.Security.Optimizely/Features/Csp/Reporting/CspReportingController.cs | Uses route context for report ingestion; adds context-aware report summary endpoint. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/Service/ICspPermissionService.cs | Context-aware permission CRUD + exact-context access. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/Service/CspPermissionService.cs | Context-aware caching and service methods. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/Save/SavePermissionModel.cs | Adds AppId/HostName to save model. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/Save/AppendPermissionModel.cs | Adds AppId/HostName to append model. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/Repository/ICspPermissionRepository.cs | Context-aware repository API. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/List/ICspPermissionsListModelBuilder.cs | Adds context setters for view model builder. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/List/CspPermissionsListModelBuilder.cs | Builds list from exact context; adds default self only for global context. |
| src/Stott.Security.Optimizely/Features/Csp/Permissions/CspPermissionsController.cs | Context-aware list/save/append + new inherited list endpoint; sanitizes host input. |
| src/Stott.Security.Optimizely/Features/Csp/Nonce/NonceTagHelper.cs | Constructor injection cleanup; still emits nonce attribute using provider. |
| src/Stott.Security.Optimizely/Features/Csp/Nonce/NonceService.cs | Nonce settings now cached per context. |
| src/Stott.Security.Optimizely/Features/Csp/Nonce/INonceService.cs | Nonce settings retrieval now context-aware via route data input. |
| src/Stott.Security.Optimizely/Features/Csp/Nonce/INonceProvider.cs | CSP nonce value retrieval now async. |
| src/Stott.Security.Optimizely/Features/Csp/Nonce/DefaultNonceProvider.cs | Async route-aware nonce enablement checks; async CSP value generation. |
| src/Stott.Security.Optimizely/Features/Csp/CspService.cs | Uses context-aware settings/sandbox/sources for compilation. |
| src/Stott.Security.Optimizely/Features/Csp/AllowList/IAllowListService.cs | Context-aware allowlist operations. |
| src/Stott.Security.Optimizely/Features/Csp/AllowList/AllowListService.cs | Uses context-aware settings and writes CSP permissions by context. |
| src/Stott.Security.Optimizely/Features/Configuration/SecurityAdminMenuProvider.cs | Consolidates CSP menu entries into one “Content Security Policy” link. |
| src/Stott.Security.Optimizely/Features/Applications/HostViewModel.cs | Adds host type/language fields for UI display. |
| src/Stott.Security.Optimizely/Extensions/StringExtensions.cs | Adds host domain sanitization helper. |
| src/Stott.Security.Optimizely/Entities/PermissionPolicySettings.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/PermissionPolicy.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/CustomHeader.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/CspViolationSummary.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/CspSource.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/CspSettings.cs | Adds context columns + lookup index. |
| src/Stott.Security.Optimizely/Entities/CspSandbox.cs | Adds context columns + lookup index; implements sandbox settings interface. |
| src/Stott.Security.Optimizely/Entities/CspDataContext.cs | Improves audit identifiers to include context. |
| src/Stott.Security.Optimizely.Test/Features/Header/HeaderCompilationServiceTests.cs | Updates cache key expectations to include context suffix. |
| src/Stott.Security.Optimizely.Test/Features/CustomHeaders/Repository/CustomHeaderRepositoryTests.cs | Updates tests for context-aware repository API. |
| src/Stott.Security.Optimizely.Test/Features/CustomHeaders/Models/SaveCustomHeaderModelTests.cs | Updates duplicate validation mocks for context-aware checks. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Settings/Service/CspSettingsServiceTests.cs | Updates tests for context-aware service API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Settings/Repository/CspSettingsRepositoryTests.cs | Updates tests for context-aware repository API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Sandbox/Service/CspSandboxServiceTests.cs | Updates tests for context-aware service API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Sandbox/Repository/CspSandboxRepositoryTests.cs | Updates tests for context-aware repository API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Reporting/ViolationReportSummaryTests.cs | Updates tests for new summary constructor signature. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Reporting/Service/CspViolationReportServiceTests.cs | Updates tests for context-aware service API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Reporting/Repository/CspViolationReportRepositoryTests.cs | Updates tests for context-aware repository API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Permissions/Service/CspPermissionServiceTests.cs | Updates tests for context-aware service API and caching. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Permissions/Repository/CspPermissionRepositoryTests.cs | Updates tests for context-aware repository API. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Permissions/List/CspPermissionsViewModelBuilderTests.cs | Updates mocks to use exact-context permission retrieval. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Permissions/CspPermissionsControllerTests.cs | Updates mocks for context-aware permission service calls. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Nonce/NonceServiceTests.cs | Updates tests to include route context and context-aware repo calls. |
| src/Stott.Security.Optimizely.Test/Features/Csp/Nonce/DefaultNonceProviderTests.cs | Updates tests for async CSP nonce value + async route helper. |
| Sample/OptimizelyTwelveTest/appsettings.json | Removes explicit urls entry. |
| Sample/OptimizelyTwelveTest/appsettings.Development.json | Deleted (now ignored in git). |
| Sample/OptimizelyTwelveTest/Properties/launchSettings.json | Simplifies launch profile URL. |
| Sample/OptimizelyTwelveTest/Program.cs | Adds dev Kestrel HTTPS listeners/limits to support multi-site testing. |
| Sample/OptimizelyTwelveTest/Features/Home/HomePageController.cs | Updates to new context-aware CSP settings service methods. |
| Sample/OptimizelyTwelveTest/Features/Configuration/SetupMigrationStep.cs | Creates multiple sites/hosts for local multi-site testing. |
| .gitignore | Ignores appsettings.Development.json. |
Files not reviewed (1)
- src/Stott.Security.Optimizely/Migrations/20260323231302_AddMultiSiteSupport.Designer.cs: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+58
to
+61
| {applications.map((app) => ( | ||
| <div key={app.appId}> | ||
| <ListGroup.Item action active={appId === app.appId && !hostName} onClick={() => handleSelectApp(app)} className="ps-3"> | ||
| <strong>{app.appName}</strong> |
There was a problem hiding this comment.
applications API inserts a "All Applications" entry with AppId = null, so using key={app.appId} here can produce a null React key (and potential rendering issues/warnings). Use a stable fallback key (e.g., 'global') when app.appId is null/empty.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.