public AuditTests(AuditTestFixture fixture) { _fixture = fixture; _client = fixture.FhirClient; _auditLogger = _fixture.AuditLogger; _client.DeleteAllResources(ResourceType.Patient).Wait(); }
public async Task WhenCreatingAResource_GivenAClientWithNoAuthToken_TheServerShouldReturnUnauthorized() { FhirClient tempClient = Client.CreateClientForClientApplication(TestApplications.InvalidClient); FhirException fhirException = await Assert.ThrowsAsync <FhirException>(async() => await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>())); Assert.Equal(UnauthorizedMessage, fhirException.Message); Assert.Equal(HttpStatusCode.Unauthorized, fhirException.StatusCode); List <AuthenticationHeaderValue> wwwAuthenticationHeaderValues = fhirException.Headers.WwwAuthenticate.Where(h => h.Scheme == "Bearer").ToList(); Assert.Single(wwwAuthenticationHeaderValues); Match matchResults = WwwAuthenticatePattern.Match(wwwAuthenticationHeaderValues.First().Parameter); Assert.Single(matchResults.Groups["authorization_uri"].Captures); var authorizationUri = matchResults.Groups["authorization_uri"].Captures[0].Value; Assert.Single(matchResults.Groups["realm"].Captures); var realm = matchResults.Groups["realm"].Captures[0].Value; Assert.Single(matchResults.Groups["resource_id"].Captures); var resourceId = matchResults.Groups["resource_id"].Captures[0].Value; Assert.Equal(AuthenticationSettings.Resource, realm); Assert.Equal(realm, resourceId); // We can only verify that this is a URI since a server with SmartOnFHIR enabled will not report the actual authorization server anywhere else. Assert.True(Uri.TryCreate(authorizationUri, UriKind.Absolute, out _)); }
private async Task ExecuteAndValidate(Func <FhirClient, Task> clientSetup, HttpStatusCode expectedStatusCode) { if (!_fixture.IsUsingInProcTestServer || !_fixture.FhirClient.SecuritySettings.SecurityEnabled) { // This test only works with the in-proc server with customized middleware pipeline and when security is enabled. return; } const string url = "Patient/123"; // Create a new client with no token supplied. var client = new FhirClient(_fixture.CreateHttpClient(), ResourceFormat.Json); await clientSetup(client); FhirResponse <OperationOutcome> response = (await Assert.ThrowsAsync <FhirException>(() => client.ReadAsync <Patient>(url))).Response; string correlationId = response.Headers.GetValues(RequestIdHeaderName).FirstOrDefault(); Assert.NotNull(correlationId); var expectedUri = new Uri($"http://localhost/{url}"); Assert.Collection( _auditLogger.GetAuditEntriesByCorrelationId(correlationId), ae => ValidateExecutedAuditEntry(ae, "read", ResourceType.Patient, expectedUri, expectedStatusCode, correlationId)); }
public SmartProxyTestFixture() { string environmentUrl = Environment.GetEnvironmentVariable("TestEnvironmentUrl"); // Only set up test fixture if running against remote server if (!string.IsNullOrWhiteSpace(environmentUrl)) { var baseUrl = "https://localhost:" + Port; SmartLauncherUrl = baseUrl + "/index.html"; Environment.SetEnvironmentVariable("FhirServerUrl", environmentUrl); Environment.SetEnvironmentVariable("ClientId", TestApplications.NativeClient.ClientId); Environment.SetEnvironmentVariable("DefaultSmartAppUrl", "/sampleapp/launch.html"); var builder = WebHost.CreateDefaultBuilder() .ConfigureAppConfiguration((hostingContext, config) => { config.AddEnvironmentVariables(); }) .UseStartup <SmartLauncher.Startup>() .UseUrls(baseUrl); WebServer = builder.Build(); WebServer.Start(); HttpClient = new HttpClient { BaseAddress = new Uri(environmentUrl), }; FhirClient = new FhirClient(HttpClient, ResourceFormat.Json); } }
public async Task WhenCreatingAResource_GivenAUserWithNoCreatePermissions_TheServerShouldReturnForbidden() { FhirClient tempClient = Client.CreateClientForUser(TestUsers.ReadOnlyUser, TestApplications.NativeClient); FhirException fhirException = await Assert.ThrowsAsync <FhirException>(async() => await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>())); Assert.Equal(ForbiddenMessage, fhirException.Message); Assert.Equal(HttpStatusCode.Forbidden, fhirException.StatusCode); }
public async Task WhenCreatingAResource_GivenAClientWithWrongAudience_TheServerShouldReturnUnauthorized() { FhirClient tempClient = Client.CreateClientForClientApplication(TestApplications.WrongAudienceClient); FhirException fhirException = await Assert.ThrowsAsync <FhirException>(async() => await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>())); Assert.Equal(UnauthorizedMessage, fhirException.Message); Assert.Equal(HttpStatusCode.Unauthorized, fhirException.StatusCode); }
public async Task WhenExportResources_GivenAUserWithNoExportPermissions_TheServerShouldReturnForbidden() { FhirClient tempClient = Client.CreateClientForUser(TestUsers.ReadOnlyUser, TestApplications.NativeClient); FhirException fhirException = await Assert.ThrowsAsync <FhirException>(async() => await tempClient.ExportAsync(_exportQueryParams)); Assert.Equal(ForbiddenMessage, fhirException.Message); Assert.Equal(HttpStatusCode.Forbidden, fhirException.StatusCode); }
public async Task WhenCreatingAResource_GivenAClientWithInvalidAuthToken_TheServerShouldReturnUnauthorized() { FhirClient tempClient = Client.CreateClientForClientApplication(TestApplications.InvalidClient).Clone(); tempClient.HttpClient.SetBearerToken(Invalidtoken); FhirException fhirException = await Assert.ThrowsAsync <FhirException>(async() => await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>())); Assert.Equal(UnauthorizedMessage, fhirException.Message); Assert.Equal(HttpStatusCode.Unauthorized, fhirException.StatusCode); }
public async Task WhenGettingAResource_GivenAUserWithReadPermissions_TheServerShouldReturnSuccess() { FhirClient tempClient = Client.CreateClientForClientApplication(TestApplications.ServiceClient); Observation createdResource = await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>()); tempClient = Client.CreateClientForUser(TestUsers.ReadOnlyUser, TestApplications.NativeClient); FhirResponse <Observation> readResponse = await tempClient.ReadAsync <Observation>(ResourceType.Observation, createdResource.Id); Observation readResource = readResponse.Resource; Assert.Equal(createdResource.Id, readResource.Id); Assert.Equal(createdResource.Meta.VersionId, readResource.Meta.VersionId); Assert.Equal(createdResource.Meta.LastUpdated, readResource.Meta.LastUpdated); }
public async Task GivenARequest_WhenInvalidAuthorizationTokenIsSupplied_ThenAuditLogEntriesShouldBeCreated() { await ExecuteAndValidate( () => { FhirClient newClient = _client.Clone(); newClient.HttpClient.SetBearerToken("invalid"); return(newClient); }, HttpStatusCode.Unauthorized, expectedAppId : null); }
public static async Task <TResource[]> CreateResourcesAsync <TResource>(this FhirClient client, int count) where TResource : Resource, new() { TResource[] resources = new TResource[count]; for (int i = 0; i < resources.Length; i++) { TResource resource = new TResource(); resources[i] = await client.CreateAsync(resource); } return(resources); }
public async Task GivenARequest_WhenNoAuthorizationTokenIsSupplied_ThenAuditLogEntriesShouldBeCreated() { await ExecuteAndValidate( () => { FhirClient newClient = _client.Clone(); newClient.HttpClient.DefaultRequestHeaders.Authorization = null; return(newClient); }, HttpStatusCode.Unauthorized, expectedAppId : null); }
public static async Task <TResource[]> CreateResourcesAsync <TResource>(this FhirClient client, params Action <TResource>[] resourceCustomizer) where TResource : Resource, new() { TResource[] resources = new TResource[resourceCustomizer.Length]; for (int i = 0; i < resources.Length; i++) { TResource resource = new TResource(); resourceCustomizer[i](resource); resources[i] = await client.CreateAsync(resource); } return(resources); }
public static async Task DeleteAllResources(this FhirClient client, ResourceType resourceType, string searchUrl) { while (true) { Bundle bundle = await client.SearchAsync(resourceType, searchUrl, count : 100); if (!bundle.Entry.Any()) { break; } foreach (Bundle.EntryComponent entry in bundle.Entry) { await client.DeleteAsync(entry.FullUrl); } } }
public async Task WhenUpdatingAResource_GivenAUserWithUpdatePermissions_TheServerShouldReturnSuccess() { FhirClient tempClient = Client.CreateClientForUser(TestUsers.AdminUser, TestApplications.NativeClient); Observation createdResource = await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>()); tempClient = Client.CreateClientForUser(TestUsers.ReadWriteUser, TestApplications.NativeClient); FhirResponse <Observation> updateResponse = await tempClient.UpdateAsync(createdResource); Assert.Equal(System.Net.HttpStatusCode.OK, updateResponse.StatusCode); Observation updatedResource = updateResponse.Resource; Assert.NotNull(updatedResource); Assert.Equal(createdResource.Id, updatedResource.Id); Assert.NotEqual(createdResource.Meta.VersionId, updatedResource.Meta.VersionId); Assert.NotEqual(createdResource.Meta.LastUpdated, updatedResource.Meta.LastUpdated); }
public async Task GivenABatchAndUserWithoutWrite_WhenPost_ThenAuditLogEntriesShouldBeCreated() { var batch = new Bundle { Type = Bundle.BundleType.Batch, Entry = new List <Bundle.EntryComponent> { new Bundle.EntryComponent { Resource = Samples.GetDefaultObservation().ToPoco(), Request = new Bundle.RequestComponent { Method = Bundle.HTTPVerb.POST, Url = "Observation", }, }, new Bundle.EntryComponent { Request = new Bundle.RequestComponent { Method = Bundle.HTTPVerb.GET, Url = "Patient?name=peter", }, }, }, }; List <(string expectedActions, string expectedPathSegments, HttpStatusCode?expectedStatusCodes, ResourceType?resourceType)> expectedList = new List <(string, string, HttpStatusCode?, ResourceType?)> { ("batch", string.Empty, HttpStatusCode.OK, ResourceType.Bundle), ("create", "Observation", HttpStatusCode.Forbidden, ResourceType.Observation), ("search-type", "Patient?name=peter", HttpStatusCode.OK, ResourceType.Bundle), }; FhirClient tempClient = _client.CreateClientForUser(TestUsers.ReadOnlyUser, TestApplications.NativeClient); await ExecuteAndValidateBundle( () => tempClient.PostBundleAsync(batch), expectedList, TestApplications.NativeClient.ClientId); }
public async Task WhenHardDeletingAResource_GivenAUserWithHardDeletePermissions_TheServerShouldReturnSuccess() { FhirClient tempClient = Client.CreateClientForUser(TestUsers.WriteOnlyUser, TestApplications.NativeClient); Observation createdResource = await tempClient.CreateAsync(Samples.GetDefaultObservation().ToPoco <Observation>()); tempClient = Client.CreateClientForUser(TestUsers.HardDeleteUser, TestApplications.NativeClient); // Hard-delete the resource. await tempClient.HardDeleteAsync(createdResource); tempClient = Client.CreateClientForUser(TestUsers.ReadOnlyUser, TestApplications.NativeClient); // Getting the resource should result in NotFound. await ExecuteAndValidateNotFoundStatus(() => tempClient.ReadAsync <Observation>(ResourceType.Observation, createdResource.Id)); async Task <FhirException> ExecuteAndValidateNotFoundStatus(Func <Task> action) { FhirException exception = await Assert.ThrowsAsync <FhirException>(action); Assert.Equal(HttpStatusCode.NotFound, exception.StatusCode); return(exception); } }
public async Task WhenExportResources_GivenAUserWithExportPermissions_TheServerShouldReturnSuccess() { FhirClient tempClient = Client.CreateClientForUser(TestUsers.ExportUser, TestApplications.NativeClient); await tempClient.ExportAsync(_exportQueryParams); }
public AuditTests(AuditTestFixture fixture) { _fixture = fixture; _client = fixture.FhirClient; _auditLogger = _fixture.AuditLogger; }
public static async Task DeleteAllResources(this FhirClient client, ResourceType resourceType) { await DeleteAllResources(client, resourceType, null); }