15
15
*/
16
16
package io .fabric8 .kubernetes .client .utils ;
17
17
18
+ import io .fabric8 .kubernetes .api .model .AuthProviderConfig ;
18
19
import io .fabric8 .kubernetes .api .model .AuthProviderConfigBuilder ;
19
20
import io .fabric8 .kubernetes .api .model .NamedContext ;
20
21
import io .fabric8 .kubernetes .client .Config ;
21
22
import io .fabric8 .kubernetes .client .ConfigBuilder ;
22
- import io .fabric8 .kubernetes .client .http .HttpClient ;
23
- import io .fabric8 .kubernetes .client .http .HttpResponse ;
23
+ import io .fabric8 .kubernetes .client .http .TestStandardHttpClient ;
24
+ import io .fabric8 .kubernetes .client .http .TestStandardHttpClientBuilder ;
25
+ import io .fabric8 .kubernetes .client .http .TestStandardHttpClientFactory ;
24
26
import io .fabric8 .kubernetes .client .internal .KubeConfigUtils ;
25
27
import io .fabric8 .kubernetes .client .internal .SSLUtils ;
28
+ import org .junit .jupiter .api .BeforeEach ;
26
29
import org .junit .jupiter .api .Test ;
27
30
import org .junit .jupiter .api .io .TempDir ;
28
31
import org .mockito .MockedStatic ;
29
- import org .mockito .Mockito ;
30
32
31
33
import java .io .File ;
32
34
import java .io .FileInputStream ;
33
35
import java .io .IOException ;
34
- import java .net .HttpURLConnection ;
35
36
import java .nio .charset .StandardCharsets ;
36
37
import java .nio .file .Files ;
37
38
import java .nio .file .Paths ;
40
41
import java .util .Base64 ;
41
42
import java .util .HashMap ;
42
43
import java .util .Map ;
43
- import java .util .concurrent .CompletableFuture ;
44
44
45
+ import static io .fabric8 .kubernetes .client .http .TestStandardHttpClientFactory .Mode .SINGLETON ;
45
46
import static io .fabric8 .kubernetes .client .utils .OpenIDConnectionUtils .CLIENT_ID_KUBECONFIG ;
46
47
import static io .fabric8 .kubernetes .client .utils .OpenIDConnectionUtils .CLIENT_SECRET_KUBECONFIG ;
47
48
import static io .fabric8 .kubernetes .client .utils .OpenIDConnectionUtils .ID_TOKEN_KUBECONFIG ;
55
56
import static org .junit .jupiter .api .Assertions .assertFalse ;
56
57
import static org .junit .jupiter .api .Assertions .assertNotNull ;
57
58
import static org .junit .jupiter .api .Assertions .assertTrue ;
58
- import static org .mockito .ArgumentMatchers .any ;
59
59
import static org .mockito .ArgumentMatchers .anyBoolean ;
60
60
import static org .mockito .ArgumentMatchers .eq ;
61
61
import static org .mockito .ArgumentMatchers .isNull ;
62
- import static org .mockito .Mockito .RETURNS_DEEP_STUBS ;
63
- import static org .mockito .Mockito .mock ;
64
62
import static org .mockito .Mockito .mockStatic ;
65
- import static org .mockito .Mockito .when ;
66
63
67
64
class OpenIDConnectionUtilsTest {
68
- HttpClient mockClient = mock (HttpClient .class , Mockito .RETURNS_DEEP_STUBS );
69
65
70
- @ Test
71
- void testLoadTokenURL () throws Exception {
72
- // Given
73
- String openIdIssuer = "https://accounts.example.com" ;
74
- String tokenEndpointResponse = "{\" issuer\" : \" https://accounts.example.com\" ," +
75
- " \" token_endpoint\" : \" https://oauth2.exampleapis.com/token\" }" ;
76
- mockHttpClient (HttpURLConnection .HTTP_OK , tokenEndpointResponse );
77
-
78
- // When
79
- Map <String , Object > discoveryDocumentMap = OpenIDConnectionUtils .getOIDCDiscoveryDocumentAsMap (mockClient , openIdIssuer )
80
- .get ();
66
+ private TestStandardHttpClient httpClient ;
67
+ private TestStandardHttpClientBuilder singletonHttpClientBuilder ;
81
68
82
- // Then
83
- assertNotNull (discoveryDocumentMap );
84
- assertEquals ("https://oauth2.exampleapis.com/token" , discoveryDocumentMap .get (TOKEN_ENDPOINT_PARAM ));
69
+ @ BeforeEach
70
+ void setUp () {
71
+ final TestStandardHttpClientFactory factory = new TestStandardHttpClientFactory (SINGLETON );
72
+ httpClient = factory .newBuilder ().build ();
73
+ singletonHttpClientBuilder = factory .newBuilder ();
85
74
}
86
75
87
76
@ Test
88
- void testLoadTokenURLWhenNotFound () throws Exception {
77
+ void loadTokenURL () throws Exception {
89
78
// Given
90
- String openIdIssuer = "https://accounts.example.com" ;
91
- String tokenEndpointResponse = "{}" ;
92
- mockHttpClient (HttpURLConnection .HTTP_NOT_FOUND , tokenEndpointResponse );
93
-
79
+ httpClient .expect ("/.well-known/openid-configuration" , 200 ,
80
+ "{\" issuer\" : \" https://accounts.example.com\" ,\" token_endpoint\" : \" https://oauth2.exampleapis.com/token\" }" );
94
81
// When
95
- Map <String , Object > discoveryDocumentAsMap = OpenIDConnectionUtils .getOIDCDiscoveryDocumentAsMap (mockClient , openIdIssuer )
82
+ Map <String , Object > result = OpenIDConnectionUtils .getOIDCDiscoveryDocumentAsMap (httpClient , "https://accounts.example.com" )
96
83
.get ();
97
-
98
84
// Then
99
- assertTrue (discoveryDocumentAsMap .isEmpty ());
85
+ assertThat (result )
86
+ .isNotNull ()
87
+ .containsEntry ("token_endpoint" , "https://oauth2.exampleapis.com/token" );
100
88
}
101
89
102
90
@ Test
103
- void testGetWellKnownUrlForOpenIDIssuer () {
91
+ void loadTokenURLWhenNotFound () throws Exception {
104
92
// Given
105
- String openIdIssuer = "https://accounts.example.com" ;
106
-
93
+ httpClient .expect ("/.well-known/openid-configuration" , 404 );
107
94
// When
108
- String wellKnownUrl = OpenIDConnectionUtils .getWellKnownUrlForOpenIDIssuer ( openIdIssuer );
109
-
95
+ Map < String , Object > result = OpenIDConnectionUtils .getOIDCDiscoveryDocumentAsMap ( httpClient , "https://accounts.example.com" )
96
+ . get ();
110
97
// Then
111
- assertEquals ( "https://accounts.example.com/.well-known/openid-configuration" , wellKnownUrl );
98
+ assertThat ( result ). isEmpty ( );
112
99
}
113
100
114
101
@ Test
115
- void testRefreshOidcToken () throws Exception {
102
+ void refreshOidcToken () throws Exception {
116
103
// Given
117
104
String clientId = "test-client-id" ;
118
105
String refreshToken = "test-refresh-token" ;
119
106
String clientSecret = "test-client-secret" ;
120
107
String tokenEndpointUrl = "https://oauth2.exampleapis.com/token" ;
121
- mockHttpClient (HttpURLConnection .HTTP_OK ,
122
- "{\" " + ID_TOKEN_PARAM + "\" :\" thisisatesttoken\" ,\" access_token\" : \" thisisrefreshtoken\" ," +
123
- "\" expires_in\" : 3599," +
124
- "\" scope\" : \" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
125
- "\" token_type\" : \" Bearer\" }" );
126
-
108
+ httpClient .expect ("/token" , 200 , "{" +
109
+ "\" id_token\" :\" thisisatesttoken\" ," +
110
+ "\" access_token\" :\" thisisrefreshtoken\" ," +
111
+ "\" expires_in\" :3599," +
112
+ "\" scope\" :\" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
113
+ "\" token_type\" :\" Bearer\" " +
114
+ "}" );
127
115
// When
128
- Map <String , Object > response = OpenIDConnectionUtils
129
- .refreshOidcToken (mockClient , clientId , refreshToken , clientSecret , tokenEndpointUrl ).get ();
130
-
116
+ Map <String , Object > result = OpenIDConnectionUtils
117
+ .refreshOidcToken (httpClient , clientId , refreshToken , clientSecret , tokenEndpointUrl ).get ();
131
118
// Then
132
- assertNotNull (response );
133
- assertEquals ("thisisatesttoken" , response .get (ID_TOKEN_PARAM ));
119
+ assertThat (result )
120
+ .isNotNull ()
121
+ .containsEntry ("id_token" , "thisisatesttoken" );
134
122
}
135
123
136
124
@ Test
137
- void testFetchOIDCProviderDiscoveryDocumentAndRefreshToken () throws Exception {
125
+ void fetchOIDCProviderDiscoveryDocumentAndRefreshToken () throws Exception {
138
126
// Given
139
127
Map <String , Object > discoveryDocument = new HashMap <>();
140
- discoveryDocument .put (TOKEN_ENDPOINT_PARAM , "https://oauth2.exampleapis.com/token" );
128
+ discoveryDocument .put ("token_endpoint" , "https://oauth2.exampleapis.com/token" );
141
129
String clientId = "test-client-id" ;
142
130
String refreshToken = "test-refresh-token" ;
143
131
String clientSecret = "test-client-secret" ;
144
- mockHttpClient (HttpURLConnection .HTTP_OK ,
145
- "{\" " + ID_TOKEN_PARAM + "\" :\" thisisatesttoken\" ,\" access_token\" : \" thisisrefreshtoken\" ," +
146
- "\" expires_in\" : 3599," +
147
- "\" scope\" : \" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
148
- "\" token_type\" : \" Bearer\" }" );
149
-
132
+ httpClient .expect ("/token" , 200 , "{" +
133
+ "\" id_token\" :\" thisisatesttoken\" ," +
134
+ "\" access_token\" :\" thisisrefreshtoken\" ," +
135
+ "\" expires_in\" :3599," +
136
+ "\" scope\" :\" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
137
+ "\" token_type\" :\" Bearer\" " +
138
+ "}" );
150
139
// When
151
- String newAccessToken = String . valueOf ( OpenIDConnectionUtils .refreshOidcToken (mockClient ,
140
+ Map < String , Object > result = OpenIDConnectionUtils .refreshOidcToken (httpClient ,
152
141
clientId , refreshToken , clientSecret ,
153
- OpenIDConnectionUtils .getParametersFromDiscoveryResponse (discoveryDocument , TOKEN_ENDPOINT_PARAM )).get ()
154
- .get (ID_TOKEN_PARAM ));
155
-
142
+ OpenIDConnectionUtils .getParametersFromDiscoveryResponse (discoveryDocument , "token_endpoint" )).get ();
156
143
// Then
157
- assertNotNull (newAccessToken );
158
- assertEquals ("thisisatesttoken" , newAccessToken );
144
+ assertThat (result )
145
+ .isNotNull ()
146
+ .containsEntry ("id_token" , "thisisatesttoken" );
159
147
}
160
148
161
149
@ Test
162
- void testPersistKubeConfigWithUpdatedToken () throws IOException {
150
+ void persistKubeConfigWithUpdatedToken () throws IOException {
163
151
// Given
164
152
Map <String , Object > openIdProviderResponse = new HashMap <>();
165
153
openIdProviderResponse .put (ID_TOKEN_PARAM , "id-token-updated" );
@@ -196,7 +184,7 @@ void testPersistKubeConfigWithUpdatedToken() throws IOException {
196
184
}
197
185
198
186
@ Test
199
- void testResolveOIDCTokenFromAuthConfigShouldReturnOldTokenWhenRefreshNotSupported () throws Exception {
187
+ void resolveOIDCTokenFromAuthConfigShouldReturnOldTokenWhenRefreshNotSupported () throws Exception {
200
188
// Given
201
189
Map <String , String > currentAuthProviderConfig = new HashMap <>();
202
190
currentAuthProviderConfig .put (CLIENT_ID_KUBECONFIG , "client-id" );
@@ -220,13 +208,24 @@ void resolveOIDCTokenFromAuthConfig_whenIDPCertNotPresentInAuthConfig_thenUseCer
220
208
currentAuthProviderConfig .put (ID_TOKEN_KUBECONFIG , "id-token" );
221
209
currentAuthProviderConfig .put (REFRESH_TOKEN_KUBECONFIG , "refresh-token" );
222
210
currentAuthProviderConfig .put (ISSUER_KUBECONFIG , "https://iam.cloud.example.com/identity" );
223
- Config config = new ConfigBuilder (Config .empty ()).withCaCertData ("cert" ).build ();
224
- HttpClient .Builder builder = mock (HttpClient .Builder .class );
225
- HttpClient httpClient = mock (HttpClient .class , RETURNS_DEEP_STUBS );
226
- when (builder .build ()).thenReturn (httpClient );
211
+ Config config = new ConfigBuilder (Config .empty ())
212
+ .withCaCertData ("cert" )
213
+ .withAuthProvider (new AuthProviderConfig ())
214
+ .build ();
215
+ httpClient .expect ("/identity/.well-known/openid-configuration" , 200 , "{" +
216
+ "\" issuer\" :\" https://iam.cloud.example.com/identity\" ," +
217
+ "\" token_endpoint\" :\" https://iam.cloud.example.com/identity/token\" " +
218
+ "}" );
219
+ httpClient .expect ("/identity/token" , 200 , "{" +
220
+ "\" id_token\" :\" thisisatesttoken\" ," +
221
+ "\" access_token\" :\" thisisrefreshtoken\" ," +
222
+ "\" expires_in\" :3599," +
223
+ "\" scope\" :\" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
224
+ "\" token_type\" :\" Bearer\" " +
225
+ "}" );
227
226
228
227
// When
229
- OpenIDConnectionUtils .resolveOIDCTokenFromAuthConfig (config , currentAuthProviderConfig , builder ).get ();
228
+ OpenIDConnectionUtils .resolveOIDCTokenFromAuthConfig (config , currentAuthProviderConfig , singletonHttpClientBuilder ).get ();
230
229
231
230
// Then
232
231
String decodedCert = new String (java .util .Base64 .getDecoder ().decode ("cert" ));
@@ -249,13 +248,24 @@ void resolveOIDCTokenFromAuthConfig_whenIDPCertNotPresentInAuthConfig_thenUseCer
249
248
currentAuthProviderConfig .put (ID_TOKEN_KUBECONFIG , "id-token" );
250
249
currentAuthProviderConfig .put (REFRESH_TOKEN_KUBECONFIG , "refresh-token" );
251
250
currentAuthProviderConfig .put (ISSUER_KUBECONFIG , "https://iam.cloud.example.com/identity" );
252
- Config config = new ConfigBuilder (Config .empty ()).withCaCertFile (caCertFile .getAbsolutePath ()).build ();
253
- HttpClient .Builder builder = mock (HttpClient .Builder .class );
254
- HttpClient httpClient = mock (HttpClient .class , RETURNS_DEEP_STUBS );
255
- when (builder .build ()).thenReturn (httpClient );
251
+ Config config = new ConfigBuilder (Config .empty ())
252
+ .withCaCertFile (caCertFile .getAbsolutePath ())
253
+ .withAuthProvider (new AuthProviderConfig ())
254
+ .build ();
255
+ httpClient .expect ("/identity/.well-known/openid-configuration" , 200 , "{" +
256
+ "\" issuer\" :\" https://iam.cloud.example.com/identity\" ," +
257
+ "\" token_endpoint\" :\" https://iam.cloud.example.com/identity/token\" " +
258
+ "}" );
259
+ httpClient .expect ("/identity/token" , 200 , "{" +
260
+ "\" id_token\" :\" thisisatesttoken\" ," +
261
+ "\" access_token\" :\" thisisrefreshtoken\" ," +
262
+ "\" expires_in\" :3599," +
263
+ "\" scope\" :\" openid https://www.exampleapis.com/auth/userinfo.email\" ," +
264
+ "\" token_type\" :\" Bearer\" " +
265
+ "}" );
256
266
257
267
// When
258
- OpenIDConnectionUtils .resolveOIDCTokenFromAuthConfig (config , currentAuthProviderConfig , builder ).get ();
268
+ OpenIDConnectionUtils .resolveOIDCTokenFromAuthConfig (config , currentAuthProviderConfig , singletonHttpClientBuilder ).get ();
259
269
260
270
// Then
261
271
sslUtilsMockedStatic .verify (() -> SSLUtils .trustManagers (eq ("cert" ), isNull (), anyBoolean (), isNull (), isNull ()));
@@ -265,7 +275,7 @@ void resolveOIDCTokenFromAuthConfig_whenIDPCertNotPresentInAuthConfig_thenUseCer
265
275
}
266
276
267
277
@ Test
268
- void testgetParametersFromDiscoveryResponse () {
278
+ void getParametersFromDiscoveryResponse () {
269
279
// Given
270
280
Map <String , Object > discoveryDocument = new HashMap <>();
271
281
discoveryDocument .put ("issuer" , "https://api.login.example.com" );
@@ -314,19 +324,6 @@ void idTokenExpired_whenTokenStillNotExpired_thenReturnFalse() {
314
324
assertThat (OpenIDConnectionUtils .idTokenExpired (createNewConfigWithAuthProviderIdToken (token ))).isFalse ();
315
325
}
316
326
317
- private void mockHttpClient (int responseCode , String responseAsStr ) throws IOException {
318
- HttpResponse <String > mockSuccessResponse = mockResponse (responseCode , responseAsStr );
319
- when (mockClient .sendAsync (any (), eq (String .class )))
320
- .thenReturn (CompletableFuture .completedFuture (mockSuccessResponse ));
321
- }
322
-
323
- private HttpResponse <String > mockResponse (int responseCode , String responseBody ) {
324
- HttpResponse <String > response = mock (HttpResponse .class , Mockito .CALLS_REAL_METHODS );
325
- Mockito .when (response .code ()).thenReturn (responseCode );
326
- Mockito .when (response .body ()).thenReturn (responseBody );
327
- return response ;
328
- }
329
-
330
327
private Config createNewConfigWithAuthProviderIdToken (String idToken ) {
331
328
return new ConfigBuilder (Config .empty ())
332
329
.withAuthProvider (new AuthProviderConfigBuilder ()
0 commit comments