Ejemplo n.º 1
0
        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);
                    }
        }
Ejemplo n.º 2
0
        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);
                    }
        }