-
Notifications
You must be signed in to change notification settings - Fork 572
Don't allow update or delete of system defined search parameters. #5288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…meter or if it doesn't exist to return correct response codes. Included related tests.
| public async Task GivenADeleteResourceRequest_WhenDeletingASystemDefinedSearchParameterResource_ThenDeleteSearchParameterShouldNotBeCalled() | ||
| { | ||
| var searchParameter = new SearchParameter() { Id = "system-param", Url = "http://hl7.org/fhir/SearchParameter/system-param" }; | ||
| var resource = searchParameter.ToTypedElement().ToResourceElement(); |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
resource
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 4 days ago
In general, to fix a “useless assignment to local variable” you either remove the unnecessary variable/assignment, or, if the result was actually meant to be used, you update the code to use it appropriately. Since resource is never read in this test, the simplest and safest change is to remove the unused local variable and its assignment, without altering any behavior of the test.
Concretely, in src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Features/Search/SearchParameters/SearchParameterBehaviorTests.cs, inside the method GivenADeleteResourceRequest_WhenDeletingASystemDefinedSearchParameterResource_ThenDeleteSearchParameterShouldNotBeCalled, remove the line:
var resource = searchParameter.ToTypedElement().ToResourceElement();No additional imports, methods, or definitions are needed, and no other lines in that method depend on resource, so no further changes are required.
| @@ -163,7 +163,6 @@ | ||
| public async Task GivenADeleteResourceRequest_WhenDeletingASystemDefinedSearchParameterResource_ThenDeleteSearchParameterShouldNotBeCalled() | ||
| { | ||
| var searchParameter = new SearchParameter() { Id = "system-param", Url = "http://hl7.org/fhir/SearchParameter/system-param" }; | ||
| var resource = searchParameter.ToTypedElement().ToResourceElement(); | ||
|
|
||
| var key = new ResourceKey("SearchParameter", "system-param"); | ||
| var request = new DeleteResourceRequest(key, DeleteOperation.SoftDelete); |
| { | ||
| private ISearchParameterOperations _searchParameterOperations; | ||
| private IFhirDataStore _fhirDataStore; | ||
| private ISearchParameterDefinitionManager _searchParameterDefinitionManager; |
Check notice
Code scanning / CodeQL
Missed 'readonly' opportunity Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 5 hours ago
In general, to fix a “Missed readonly opportunity” warning, you add the readonly modifier to any field that is only assigned at its declaration or within constructors of the same class, and never reassigned elsewhere. This ensures the field cannot be changed after the object is fully constructed.
For this specific case, the best fix is to add readonly to the three private dependency fields in DeleteSearchParameterBehavior<TDeleteResourceRequest, TDeleteResourceResponse> that are assigned in the constructor and then only read: _searchParameterOperations, _fhirDataStore, and _searchParameterDefinitionManager. Although CodeQL flagged only _searchParameterDefinitionManager, the same pattern applies to the other two fields, and marking all of them readonly improves consistency and clarity without changing behavior.
Concretely, in src/Microsoft.Health.Fhir.Core/Features/Search/Parameters/DeleteSearchParameterBehavior.cs, on lines 26–28, change:
private ISearchParameterOperations _searchParameterOperations;
private IFhirDataStore _fhirDataStore;
private ISearchParameterDefinitionManager _searchParameterDefinitionManager;to:
private readonly ISearchParameterOperations _searchParameterOperations;
private readonly IFhirDataStore _fhirDataStore;
private readonly ISearchParameterDefinitionManager _searchParameterDefinitionManager;No additional methods, imports, or definitions are required, since the rest of the code already uses these fields as immutable dependencies.
-
Copy modified lines R26-R28
| @@ -23,9 +23,9 @@ | ||
| public class DeleteSearchParameterBehavior<TDeleteResourceRequest, TDeleteResourceResponse> : IPipelineBehavior<TDeleteResourceRequest, TDeleteResourceResponse> | ||
| where TDeleteResourceRequest : DeleteResourceRequest, IRequest<TDeleteResourceResponse> | ||
| { | ||
| private ISearchParameterOperations _searchParameterOperations; | ||
| private IFhirDataStore _fhirDataStore; | ||
| private ISearchParameterDefinitionManager _searchParameterDefinitionManager; | ||
| private readonly ISearchParameterOperations _searchParameterOperations; | ||
| private readonly IFhirDataStore _fhirDataStore; | ||
| private readonly ISearchParameterDefinitionManager _searchParameterDefinitionManager; | ||
|
|
||
| public DeleteSearchParameterBehavior( | ||
| ISearchParameterOperations searchParameterOperations, |
| var systemDefinedParam = allSearchParameters.FirstOrDefault(sp => | ||
| sp.IsSystemDefined && | ||
| sp.Url.ToString().EndsWith($"/{deleteRequest.ResourceKey.Id}", StringComparison.OrdinalIgnoreCase)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using endswith could potentially grab the wrong entry. Might be more accurate to extract everything after last / and compare that to ResourceKey.id exactly.
| var systemDefinedParam = allSearchParameters.FirstOrDefault(sp => | |
| sp.IsSystemDefined && | |
| sp.Url.ToString().EndsWith($"/{deleteRequest.ResourceKey.Id}", StringComparison.OrdinalIgnoreCase)); | |
| var systemDefinedParam = allSearchParameters.FirstOrDefault(sp => | |
| sp.IsSystemDefined && | |
| sp.Url?.Segments.LastOrDefault()?.TrimEnd('/') == deleteRequest.ResourceKey.Id); |
Description
Block update for a spec defined parameter. Changed DeleteSearchParamBehavior to check if it is a system defined search parameter or if it doesn't exist to return correct response codes. Included related tests.
Related issues
Addresses https://microsofthealth.visualstudio.com/Health/_workitems/edit/179097.
Testing
Tested with rest api calls and unit tests.
FHIR Team Checklist
Semver Change (docs)
Patch|Skip|Feature|Breaking (reason)