public async void ShouldGetDataCollectionValues() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var dataCollectionRecordValuesRequest = new ListDataCollectionRecordValuesRequest(); dataCollectionRecordValuesRequest.ActionstepId = 7; dataCollectionRecordValuesRequest.TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey); dataCollectionRecordValuesRequest.DataCollectionRecordNames.AddRange(new[] { "property", "convdet", "keydates" }); dataCollectionRecordValuesRequest.DataCollectionFieldNames.AddRange(new[] { "titleref", "lotno", "planno", "plantype", "smtdateonly", "smttime", "purprice" }); var response = await actionstepService.Handle <ListDataCollectionRecordValuesResponse>(dataCollectionRecordValuesRequest); Assert.Equal(6, response.DataCollectionRecordValues.Count); Assert.Equal("test-title-ref", response["property", "titleref"]); } }
public async void ShouldListActionstepParticipants() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var request = new ListParticipantsRequest { TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }; var response = await actionstepService.Handle <ListParticipantsResponse>(request); var admin = response.Participants.SingleOrDefault(p => p.Id == 1); Assert.NotNull(admin); var expectedBirthTimestamp = new LocalDate(2000, 1, 1); var expectedDeathTimestamp = new LocalDate(2001, 1, 1); Assert.Equal(expectedBirthTimestamp, admin.BirthTimestamp); Assert.Equal(expectedDeathTimestamp, admin.DeathTimestamp); } }
public async Task ShouldRetryRefreshingInvalidToken() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var tokenHandler = new TestTokenSetRepository(); var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(isInvalid: true); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var response = await actionstepService.Handle <GetActionResponse>(new GetActionRequest { ActionId = 1, TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }); // Should be called 3 times. First from this test method to arrange this test token, second from the handler to set the lock, and third time to unlock/update with refreshed data. Assert.Equal(3, testTokenRepository.AddOrUpdateTokenSetCount); } }
public async Task ShouldGetActionWithMultipleMatterIds() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await testTokenRepository.AddOrUpdateTokenSet(testTokenSet); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var listActionsRequest = new ListActionsRequest(); listActionsRequest.ActionstepIds.AddRange(new[] { 1, 7 }); listActionsRequest.TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey); var response = await actionstepService.Handle <ListActionsResponse>(listActionsRequest); Assert.Equal(2, response.Actions.Count); Assert.True(response.Actions.Exists(a => a.Id == 1)); Assert.True(response.Actions.Exists(a => a.Id == 7)); } }
public async void ShouldGetActionWithMatterId() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var tokenSetRepository = new TestTokenSetRepository(); var testTokenSet = GetTestTokenSet(); await tokenSetRepository.AddOrUpdateTokenSet(testTokenSet); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, tokenSetRepository, fakeClock, memoryCache); var response = await actionstepService.Handle <GetActionResponse>(new GetActionRequest { ActionId = 1, TokenSetQuery = new TokenSetQuery(testTokenSet.UserId, testTokenSet.OrgKey) }); Assert.Equal(1, response.Action.Id); Assert.Null(response.Action.IsBillableOverride); Assert.False(response.Action.IsDeleted); Assert.True(response.Action.IsFavorite); } }
public void GetJwtPublicKeyThrowsOnHttpProblem() { var localHandler = A.Fake <MockHandler>(opt => opt.CallsBaseMethods()); A.CallTo(() => localHandler.SendAsync(HttpMethod.Get, "https://cdn.actionstep.com/jwt-discovery-public.json")) .ReturnsLazily(() => new HttpResponseMessage(HttpStatusCode.BadRequest)); using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = localHandler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var tokenSetRepository = new TestTokenSetRepository(); IActionstepService actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, tokenSetRepository, fakeClock, memoryCache); var ex = Assert.Throws <InvalidJwtDiscoveryResponseException>(() => { actionstepService.GetJwtPublicKeyData(); }); Assert.Equal("There was a problem retrieving the JWT Discovery public key data.", ex.Message); Assert.IsType <HttpRequestException>(ex.InnerException); } }
public BaseController() { var authDelegating = new AuthDelegatingHandler(); _httpClient = HttpClientFactory.Create(authDelegating); _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); }
public async Task ShouldRefreshAllRefreshableTokens() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = FakeClock.FromUtc(2019, 10, 10); var now = fakeClock.GetCurrentInstant(); var testTokenSetRepository = new TestTokenSetRepository(); //// Add test tokens // Valid tokens (shouldn't be refreshed) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token0", "bearer0", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now, "0", "0")); await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token1", "bearer1", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now, "1", "1")); // Nearing expiry (should be refreshed) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token2", "bearer2", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now.Minus(Duration.FromDays(18)), "2", "2")); // Expired (shouldn't be refreshed, as it will fail anyway) await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("token3", "bearer3", 3600, new Uri("https://test-endpoint/api/"), "testOrgKey", "testRefreshToken", now.Minus(Duration.FromDays(30)), "3", "3")); var actionstepServiceConfigurationOptions = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, actionstepServiceConfigurationOptions, testTokenSetRepository, fakeClock, memoryCache); var config = new ConfigurationBuilder(); config.AddInMemoryCollection(new Dictionary <string, string>() { { "WCACoreSettings:PEXASettings:Environment", "Test" } }); var wcaCoreSettingsOptions = Options.Create(config.Build().Get <WCACoreSettings>()); var refreshTokens = new RefreshAllTokens(testTokenSetRepository, actionstepService, fakeClock); await refreshTokens.Run(null, new NullLogger <RefreshAllTokens>()); Assert.Equal("token0", testTokenSetRepository.TokenSets.Single(t => t.Id == "0").AccessToken); Assert.Equal("token1", testTokenSetRepository.TokenSets.Single(t => t.Id == "1").AccessToken); Assert.Equal("updatedAccessToken", testTokenSetRepository.TokenSets.Single(t => t.Id == "2").AccessToken); Assert.Equal("token3", testTokenSetRepository.TokenSets.Single(t => t.Id == "3").AccessToken); } }
public async void ShouldRefreshActionstepToken() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var tokenHandler = new TestTokenSetRepository(); var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); // Expired token var tokenSet = new TokenSet( accessToken: "testAccessToken", tokenType: "bearer", expiresIn: 60 * 20, apiEndpoint: new Uri("https://api.uri/api/"), orgKey: "testOrgKey", refreshToken: "testRefreshToken", userId: "1", id: "tokenId", receivedAt: fakeClock.GetCurrentInstant().Minus(Duration.FromDays(365))); var response = await actionstepService.RefreshAccessTokenIfExpired(tokenSet); Assert.NotNull(response); Assert.Equal("updatedAccessToken", response.AccessToken); Assert.Equal(3600, response.ExpiresIn); Assert.Equal("updatedRefreshToken", response.RefreshToken); Assert.Equal("testOrg", response.OrgKey); Assert.Equal(new Uri("https://test-endpoint/api/"), response.ApiEndpoint); Assert.Equal("tokenId", response.Id); Assert.Equal(2, testTokenRepository.AddOrUpdateTokenSetCount); } }
public void GetJwtPublicKeyReturnsValue() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var tokenSetRepository = new TestTokenSetRepository(); IActionstepService actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, tokenSetRepository, fakeClock, memoryCache); var receivedPublicKeyJObject = actionstepService.GetJwtPublicKeyData(); var receivedPublicKey = receivedPublicKeyJObject.Value <string>(JwtPublicKeyIds.ProdPublicKey); const string EXPECTED_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2ikRwK8OpklNc3U9y2n\n3JE+B1sQftl8TbZs++PHiActfqHqVbdh2n8Pjaft2NDGB9BXOEO9I/F0J3jZJT+H\n2FdO8HoFPLfeMvcrRKvXa2UmSXRrZLA6YIf+wzgI0wgbb+lkEH3LUgHk0XxalnRE\nMmNUpAWtO0ZX2jh8tkp+3ymhzCtXHwYpiI1iJUDUje/kBXvKfdP+QcDgkshehY/w\nph5SEXS/a//r2TWRPbFHlzi96fL7ySZIjTWyQtZ1UwzjTqkA0gRYQLtXEQW5tLgJ\niiwivJ1UiGoGTfp4nj+ZU7OVYV5I/k+t4cv+s1jYAP/hmdW98932DavR9Mmlb80g\nXwIDAQAB\n-----END PUBLIC KEY-----"; Assert.Equal(EXPECTED_PUBLIC_KEY, receivedPublicKey); } }
public async Task SecondTokenRefreshWaitsForFirst() { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) using (var memoryCache = new MemoryCache(new MemoryCacheOptions())) { var tokenHandler = new TestTokenSetRepository(); var fakeClock = new FakeClock(Instant.FromUtc(2019, 05, 07, 2, 3)); var testTokenRepository = new TestTokenSetRepository(); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenRepository, fakeClock, memoryCache); var now = fakeClock.GetCurrentInstant(); /// We're using the TokenType purely as a mechanism to talk to <see cref="TestTokenSetRepository"/>. /// This allows us to delay one refresh while queueing another to ensure the locking/retry works correctly /// with concurrent refresh requests. var tokenTypeTest1 = "bearer-test1"; var tokenTypeTest2 = "bearer-test2"; // First, store a locked expired token var tokenId = "locking test token"; var tokenSet1 = new TokenSet( "testAccessToken1", tokenTypeTest1, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken1", now.Minus(Duration.FromMinutes(120)), "testUser", tokenId); tokenSet1.LockForRefresh(now.Plus(Duration.FromMinutes(60))); var storedTokenSet1 = await testTokenRepository.AddOrUpdateTokenSet(tokenSet1); // Now we set up a second expired token with the same id. var tokenSet2 = new TokenSet( "testAccessToken2", tokenTypeTest2, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken2", now.Minus(Duration.FromMinutes(120)), "testUser", tokenId); // Try to refresh using the second token (which has the same tokenId). It should be blocked by the locked token1 from above. var tokenSet2RefreshTask = actionstepService.RefreshAccessTokenIfExpired(tokenSet2, forceRefresh: false); /// Delay to give the <see cref="RefreshAccessTokenIfExpired"/> a chance to await Task.Delay(50); // Now store a valid token of test type 1, this will unlock the token tokenSet1 = new TokenSet( "testAccessToken1", tokenTypeTest1, 3600, new Uri("https://api.uri/api/auto-increment/"), "testOrgKey", "testRefreshToken1", now, "testUser", tokenId); await testTokenRepository.AddOrUpdateTokenSet(tokenSet1); tokenSet2RefreshTask.Wait(); // The token from the refresh should be the one we put in the repository. Assert.Equal(tokenTypeTest1, tokenSet2RefreshTask.Result.TokenType); } }
public async Task ShouldCreatePEXAWorkspaceRequestFromActionstep() { var testUser = await _containerFixture.GetTestUser(); await _containerFixture.ExecuteScopeAsync(async serviceProvider => { using (var authDelegatingHandler = new AuthDelegatingHandler() { InnerHandler = _handler }) using (var httpClient = new HttpClient(authDelegatingHandler)) { var fakeClock = new FakeClock(new Instant()); var testTokenSetRepository = new TestTokenSetRepository(); await testTokenSetRepository.AddOrUpdateTokenSet(new TokenSet("accessToken", "bearer", 3600, new Uri("https://uri/api"), "testOrg", "refreshToken", fakeClock.GetCurrentInstant(), testUser.Id)); var options = new ActionstepServiceConfigurationOptions("clientId", "clientSecret"); var actionstepService = new ActionstepService(new NullLogger <ActionstepService>(), httpClient, options, testTokenSetRepository, fakeClock, new MemoryCache(new MemoryCacheOptions())); var mapper = serviceProvider.GetService <IMapper>(); var actionstepToWcaMapper = serviceProvider.GetService <IActionstepToWCAMapper>(); PrepareTestData(serviceProvider); var handler = new PEXAWorkspaceCreationRequestFromActionstepQueryHandler(actionstepService, mapper, actionstepToWcaMapper); var token = new CancellationToken(); var query = new PEXAWorkspaceCreationRequestFromActionstepQuery { AuthenticatedUser = testUser, MatterId = 1, ActionstepOrg = "testOrg" }; var pexaWorkspaceCreationResponse = await handler.Handle(query, token); Assert.Equal("1", pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest.SubscriberReference); Assert.Equal("Yes", pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest.FinancialSettlement); var config = new ConfigurationBuilder(); config.AddInMemoryCollection(new Dictionary <string, string>() { { "WCACoreSettings:PEXASettings:Environment", "Test" } }); var pexaService = new PEXAService(httpClient, config.Build()); var request = new WorkspaceCreationRequestCommand(pexaWorkspaceCreationResponse.CreatePexaWorkspaceCommand.PexaWorkspaceCreationRequest, "dummyToken"); var response = await pexaService.Handle <WorkspaceCreationResponse>(request, CancellationToken.None); Assert.Equal("PEXA190167645", response.WorkspaceId); Assert.Equal("In Preparation", response.WorkspaceStatus); var xmldiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreNamespaces | XmlDiffOptions.IgnorePrefixes); var expectedXml = EmbeddedResource.Read("ResponseData.create-workspace-result.xml"); var actualXml = _handler.RequestContent; var expectedReader = XElement.Parse(expectedXml).CreateReader(); var actualReader = XElement.Parse(actualXml).CreateReader(); using (var diffStringWriter = new StringWriter()) using (var diffWriter = XmlWriter.Create(diffStringWriter)) { var areXmlIdentical = xmldiff.Compare(expectedReader, actualReader, diffWriter); diffWriter.Flush(); foreach (var diffLine in diffStringWriter.ToString().Split(diffStringWriter.NewLine)) { _output.WriteLine(diffLine); } Assert.True(areXmlIdentical); } } }); }