microsoft/healthcare-shared-components

Public

mirrored from https://github.com/microsoft/healthcare-shared-componentsAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.0.0-1.0.79

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Microsoft.Health.Client.UnitTests/CredentialProviderTests.cs

145lines · modecode

1// -------------------------------------------------------------------------------------------------
2// Copyright (c) Microsoft Corporation. All rights reserved.
3// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4// -------------------------------------------------------------------------------------------------
5
6using System;
7using System.Net;
8using System.Net.Http;
9using System.Threading;
10using System.Threading.Tasks;
11using Microsoft.Extensions.Options;
12using Microsoft.Health.Client.Exceptions;
13using Moq;
14using Moq.Protected;
15using Xunit;
16
17namespace Microsoft.Health.Client.UnitTests
18{
19 public class CredentialProviderTests
20 {
21 [Fact]
22 public async Task GivenAnNonSetToken_WhenGetBearerTokenCalled_ThenBearerTokenFunctionIsCalled()
23 {
24 var expirationTime = DateTime.UtcNow + TimeSpan.FromDays(1);
25
26 var credentialProvider = new TestCredentialProvider(JwtTokenHelpers.GenerateToken(expirationTime));
27 Assert.Null(credentialProvider.Token);
28 Assert.Equal(default, credentialProvider.TokenExpiration);
29
30 var token = await credentialProvider.GetBearerToken(cancellationToken: default);
31
32 Assert.Equal(token, credentialProvider.Token);
33
34 // JWT token expiration is limited to second precision
35 Assert.InRange(credentialProvider.TokenExpiration, expirationTime.AddSeconds(-1), expirationTime.AddSeconds(1));
36 }
37
38 [Fact]
39 public async Task InvalidOAuth2ClientCredential_RetrieveToken_ShouldThrowError()
40 {
41 var mockHandler = new Mock<HttpMessageHandler>();
42 var response = new HttpResponseMessage
43 {
44 StatusCode = HttpStatusCode.BadRequest,
45 Content = new StringContent(@"{""error"": ""This is an error!""}"),
46 };
47
48 mockHandler
49 .Protected()
50 .Setup<Task<HttpResponseMessage>>(
51 "SendAsync",
52 ItExpr.IsAny<HttpRequestMessage>(),
53 ItExpr.IsAny<CancellationToken>())
54 .ReturnsAsync(response);
55
56 var httpClient = new HttpClient(mockHandler.Object);
57
58 var credentialConfiguration = new OAuth2ClientCredentialConfiguration(
59 new Uri("https://fakehost/connect/token"),
60 "invalid resource",
61 "invalid scope",
62 "invalid client id",
63 "invalid client secret");
64 var credentialProvider = new OAuth2ClientCredentialProvider(Options.Create(credentialConfiguration), httpClient);
65 await Assert.ThrowsAsync<FailToRetrieveTokenException>(() => credentialProvider.GetBearerToken(cancellationToken: default));
66 }
67
68 [Fact]
69 public async Task InvalidOAuth2UserPasswordCredential_RetrieveToken_ShouldThrowError()
70 {
71 var mockHandler = new Mock<HttpMessageHandler>();
72 var response = new HttpResponseMessage
73 {
74 StatusCode = HttpStatusCode.BadRequest,
75 Content = new StringContent(@"{""error"": ""This is an error!""}"),
76 };
77
78 mockHandler
79 .Protected()
80 .Setup<Task<HttpResponseMessage>>(
81 "SendAsync",
82 ItExpr.IsAny<HttpRequestMessage>(),
83 ItExpr.IsAny<CancellationToken>())
84 .ReturnsAsync(response);
85
86 var httpClient = new HttpClient(mockHandler.Object);
87
88 var credentialConfiguration = new OAuth2UserPasswordCredentialConfiguration(
89 new Uri("https://fakehost/connect/token"),
90 "invalid resource",
91 "invalid scope",
92 "invalid client id",
93 "invalid client secret",
94 "invalid username",
95 "invaid password");
96 var credentialProvider = new OAuth2UserPasswordCredentialProvider(Options.Create(credentialConfiguration), httpClient);
97 await Assert.ThrowsAsync<FailToRetrieveTokenException>(() => credentialProvider.GetBearerToken(cancellationToken: default));
98 }
99
100 [Fact]
101 public async Task GivenANonExpiredToken_WhenGetBearerTokenCalled_ThenSameBearerTokenIsReturned()
102 {
103 var initialExpiration = DateTime.UtcNow + TimeSpan.FromDays(1);
104 var initialToken = JwtTokenHelpers.GenerateToken(initialExpiration);
105 var credentialProvider = new TestCredentialProvider(initialToken);
106
107 // Returns the initialToken
108 var initialResult = await credentialProvider.GetBearerToken(cancellationToken: default);
109 Assert.Equal(initialToken, initialResult);
110
111 // Update the token that would be returned if BearerTokenFunction() was called
112 var updatedExpiration = DateTime.UtcNow + TimeSpan.FromDays(1);
113 var secondToken = JwtTokenHelpers.GenerateToken(updatedExpiration);
114 credentialProvider.EncodedToken = secondToken;
115
116 // Should return the initialToken since it is not within the expiration window
117 var secondResult = await credentialProvider.GetBearerToken(cancellationToken: default);
118
119 Assert.Equal(initialResult, secondResult);
120 }
121
122 [Fact]
123 public async Task GivenAnExpiringToken_WhenGetBearerTokenCalled_ThenNewBearerTokenIsReturned()
124 {
125 var initialExpiration = DateTime.UtcNow + TimeSpan.FromMinutes(4);
126 var initialToken = JwtTokenHelpers.GenerateToken(initialExpiration);
127 var credentialProvider = new TestCredentialProvider(initialToken);
128
129 // Returns the initialToken
130 var initialResult = await credentialProvider.GetBearerToken(cancellationToken: default);
131 Assert.Equal(initialToken, initialResult);
132
133 // Update the token that will be returned since the initial token is within the expiration window
134 var updatedExpiration = DateTime.UtcNow + TimeSpan.FromDays(1);
135 var secondToken = JwtTokenHelpers.GenerateToken(updatedExpiration);
136 credentialProvider.EncodedToken = secondToken;
137
138 // Should return the initialToken since it is not within the expiration window
139 var secondResult = await credentialProvider.GetBearerToken(cancellationToken: default);
140
141 Assert.Equal(secondToken, secondResult);
142 Assert.NotEqual(initialResult, secondResult);
143 }
144 }
145}