blob: a7d108cb17e11788869b48c7e59ca992b0e765a0 [file] [log] [blame]
margarethaa0486272018-04-12 19:59:31 +02001package de.ids_mannheim.korap.web.controller;
2
margaretha05122312018-04-16 15:01:34 +02003import static org.junit.Assert.assertEquals;
margarethaf839dde2018-04-16 17:52:57 +02004import static org.junit.Assert.assertNotNull;
margaretha6f0b7382018-11-21 17:42:02 +01005import static org.junit.Assert.assertTrue;
margarethafb027f92018-04-23 20:00:13 +02006
7import java.net.URI;
margaretha93e602e2019-08-07 15:19:56 +02008import java.util.Set;
margaretha05122312018-04-16 15:01:34 +02009
margarethaa0486272018-04-12 19:59:31 +020010import javax.ws.rs.core.MultivaluedMap;
margaretha05122312018-04-16 15:01:34 +020011import javax.ws.rs.core.Response.Status;
margarethaa0486272018-04-12 19:59:31 +020012
13import org.apache.http.entity.ContentType;
margaretha05122312018-04-16 15:01:34 +020014import org.apache.oltu.oauth2.common.error.OAuthError;
margaretha03b82862018-07-12 20:09:26 +020015import org.apache.oltu.oauth2.common.message.types.GrantType;
margarethaf839dde2018-04-16 17:52:57 +020016import org.apache.oltu.oauth2.common.message.types.TokenType;
margarethaa0486272018-04-12 19:59:31 +020017import org.junit.Test;
margarethaa0486272018-04-12 19:59:31 +020018
margaretha05122312018-04-16 15:01:34 +020019import com.fasterxml.jackson.databind.JsonNode;
margarethaa0486272018-04-12 19:59:31 +020020import com.google.common.net.HttpHeaders;
margarethaa0486272018-04-12 19:59:31 +020021import com.sun.jersey.api.client.ClientResponse;
margarethaa0486272018-04-12 19:59:31 +020022import com.sun.jersey.core.util.MultivaluedMapImpl;
23
24import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
margaretha43aceb52019-11-21 12:58:53 +010025import de.ids_mannheim.korap.config.Attributes;
margarethaa0486272018-04-12 19:59:31 +020026import de.ids_mannheim.korap.exceptions.KustvaktException;
margarethabe4c5c92018-05-03 18:55:49 +020027import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
margaretha93e602e2019-08-07 15:19:56 +020028import de.ids_mannheim.korap.oauth2.entity.AccessScope;
29import de.ids_mannheim.korap.oauth2.entity.RefreshToken;
margaretha05122312018-04-16 15:01:34 +020030import de.ids_mannheim.korap.utils.JsonUtils;
margarethaa0486272018-04-12 19:59:31 +020031
32/**
33 * @author margaretha
34 *
35 */
margarethaf0085122018-08-16 16:19:53 +020036public class OAuth2ControllerTest extends OAuth2TestBase {
margarethaa0486272018-04-12 19:59:31 +020037
margarethaf0085122018-08-16 16:19:53 +020038 public String userAuthHeader;
margaretha35074692021-03-26 18:11:59 +010039
margarethaf0085122018-08-16 16:19:53 +020040 public OAuth2ControllerTest () throws KustvaktException {
41 userAuthHeader = HttpAuthorizationHandler
42 .createBasicAuthorizationHeaderValue("dory", "password");
margarethaf839dde2018-04-16 17:52:57 +020043 }
44
margarethafb027f92018-04-23 20:00:13 +020045 @Test
46 public void testAuthorizeConfidentialClient () throws KustvaktException {
margarethaffb89502022-04-20 12:03:16 +020047 // with registered redirect URI
48 ClientResponse response =
49 requestAuthorizationCode("code", confidentialClientId, "",
50 "match_info search client_info", state, userAuthHeader);
margarethadc515072018-08-03 17:01:19 +020051
52 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
53 response.getStatus());
54 URI redirectUri = response.getLocation();
margarethaffb89502022-04-20 12:03:16 +020055 MultivaluedMap<String, String> params =
56 getQueryParamsFromURI(redirectUri);
margarethadc515072018-08-03 17:01:19 +020057 assertNotNull(params.getFirst("code"));
58 assertEquals("thisIsMyState", params.getFirst("state"));
margarethaffb89502022-04-20 12:03:16 +020059 assertEquals("match_info search client_info", params.getFirst("scope"));
margarethadc515072018-08-03 17:01:19 +020060 }
61
62 @Test
63 public void testAuthorizePublicClient () throws KustvaktException {
margarethaffb89502022-04-20 12:03:16 +020064 // with registered redirect URI
margarethad67b4272022-04-11 17:34:19 +020065 String code = requestAuthorizationCode(publicClientId, userAuthHeader);
margarethaf0085122018-08-16 16:19:53 +020066 assertNotNull(code);
margarethafb027f92018-04-23 20:00:13 +020067 }
68
69 @Test
margarethaffb89502022-04-20 12:03:16 +020070 public void testAuthorizePublicClientWithRedirectUri () throws KustvaktException {
71 ClientResponse response =
72 requestAuthorizationCode("code", publicClientId2,
73 "https://public.com/redirect", "", "", userAuthHeader);
74 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
75 response.getStatus());
76
77 URI redirectUri = response.getLocation();
78 assertEquals(redirectUri.getScheme(), "https");
79 assertEquals(redirectUri.getHost(), "public.com");
80 assertEquals(redirectUri.getPath(), "/redirect");
81
82 String[] queryParts = redirectUri.getQuery().split("&");
83 assertTrue(queryParts[0].startsWith("code="));
84 assertEquals(queryParts[1], "scope=match_info+search");
85 }
86
87 @Test
88 public void testAuthorizeWithoutScope () throws KustvaktException {
89 ClientResponse response = requestAuthorizationCode("code",
90 confidentialClientId, "", "", "", userAuthHeader);
91 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
92 response.getStatus());
93
94 URI redirectUri = response.getLocation();
95 assertEquals(redirectUri.getScheme(), "https");
96 assertEquals(redirectUri.getHost(), "third.party.com");
97 assertEquals(redirectUri.getPath(), "/confidential/redirect");
98
99 String[] queryParts = redirectUri.getQuery().split("&");
100 assertTrue(queryParts[0].startsWith("code="));
101 assertEquals(queryParts[1], "scope=match_info+search");
102 }
103
104 @Test
105 public void testAuthorizeMissingClientId () throws KustvaktException {
106 ClientResponse response = requestAuthorizationCode("code", "", "", "",
107 "", userAuthHeader);
108 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
109 String entity = response.getEntity(String.class);
110 JsonNode node = JsonUtils.readTree(entity);
111 assertEquals("Missing parameters: client_id",
112 node.at("/error_description").asText());
113 }
114
115 @Test
116 public void testAuthorizeMissingRedirectUri () throws KustvaktException {
117 ClientResponse response = requestAuthorizationCode("code",
118 publicClientId2, "", "", state, userAuthHeader);
119 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
120
121 String entity = response.getEntity(String.class);
122 JsonNode node = JsonUtils.readTree(entity);
123 assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
124 node.at("/error").asText());
125 assertEquals("Redirect URI is required",
126 node.at("/error_description").asText());
127 assertEquals("thisIsMyState", node.at("/state").asText());
128 }
129
130 @Test
131 public void testAuthorizeMissingResponseType () throws KustvaktException {
132 ClientResponse response = requestAuthorizationCode("",
133 confidentialClientId, "", "", "", userAuthHeader);
134 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
135 response.getStatus());
136
137 assertEquals("https://third.party.com/confidential/redirect?"
138 + "error_description=Missing+parameters%3A+response_type&"
139 + "error=invalid_request", response.getLocation().toString());
140 }
141
142 @Test
143 public void testAuthorizeInvalidClientId () throws KustvaktException {
144 ClientResponse response = requestAuthorizationCode("code",
145 "unknown-client-id", "", "", "", userAuthHeader);
146// assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
147 String entity = response.getEntity(String.class);
148 System.out.println(entity);
149 JsonNode node = JsonUtils.readTree(entity);
150 assertEquals("Unknown client with unknown-client-id.",
151 node.at("/error_description").asText());
152 }
153
154 @Test
margarethafb027f92018-04-23 20:00:13 +0200155 public void testAuthorizeInvalidRedirectUri () throws KustvaktException {
156 String redirectUri = "https://different.uri/redirect";
margarethad67b4272022-04-11 17:34:19 +0200157 ClientResponse response = requestAuthorizationCode("code",
158 confidentialClientId, redirectUri, "", state, userAuthHeader);
margarethafb027f92018-04-23 20:00:13 +0200159
160 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
161
162 String entity = response.getEntity(String.class);
163 JsonNode node = JsonUtils.readTree(entity);
164 assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
165 node.at("/error").asText());
margarethada3c7852018-06-14 20:35:11 +0200166 assertEquals("Invalid redirect URI",
margarethafb027f92018-04-23 20:00:13 +0200167 node.at("/error_description").asText());
margarethab36b1a32018-06-20 20:13:07 +0200168 assertEquals("thisIsMyState", node.at("/state").asText());
margarethafb027f92018-04-23 20:00:13 +0200169 }
margarethafb027f92018-04-23 20:00:13 +0200170
171 @Test
172 public void testAuthorizeInvalidResponseType () throws KustvaktException {
margarethaffb89502022-04-20 12:03:16 +0200173 // without redirect URI in the request
margarethad67b4272022-04-11 17:34:19 +0200174 ClientResponse response = requestAuthorizationCode("string",
175 confidentialClientId, "", "", state, userAuthHeader);
margarethaffb89502022-04-20 12:03:16 +0200176 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
177 response.getStatus());
178
179 assertEquals("https://third.party.com/confidential/redirect?"
180 + "error_description=Invalid+response_type+parameter+"
181 + "value&state=thisIsMyState&" + "error=invalid_request",
182 response.getLocation().toString());
183
184 // with redirect URI, and no registered redirect URI
185 response = requestAuthorizationCode("string", publicClientId2,
186 "https://public.client.com/redirect", "", state,
187 userAuthHeader);
188 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
189 response.getStatus());
190
191 assertEquals("https://public.client.com/redirect?error_description="
192 + "Invalid+response_type+parameter+value&state=thisIsMyState&"
193 + "error=invalid_request", response.getLocation().toString());
194
195 // with different redirect URI
196 String redirectUri = "https://different.uri/redirect";
197 response = requestAuthorizationCode("string", confidentialClientId,
198 redirectUri, "", state, userAuthHeader);
margarethafb027f92018-04-23 20:00:13 +0200199 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
200
margarethaffb89502022-04-20 12:03:16 +0200201 JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
margarethafb027f92018-04-23 20:00:13 +0200202 assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
203 node.at("/error").asText());
margarethaffb89502022-04-20 12:03:16 +0200204 assertEquals("Invalid redirect URI",
205 node.at("/error_description").asText());
206 assertEquals("thisIsMyState", node.at("/state").asText());
207
208 // without redirect URI in the request and no registered
209 // redirect URI
210 response = requestAuthorizationCode("string", publicClientId2, "", "",
211 state, userAuthHeader);
212 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
213
214 node = JsonUtils.readTree(response.getEntity(String.class));
215 assertEquals(OAuthError.CodeResponse.INVALID_REQUEST,
216 node.at("/error").asText());
217 assertEquals("Redirect URI is required",
margarethafb027f92018-04-23 20:00:13 +0200218 node.at("/error_description").asText());
margarethab36b1a32018-06-20 20:13:07 +0200219 assertEquals("thisIsMyState", node.at("/state").asText());
margarethafb027f92018-04-23 20:00:13 +0200220 }
221
margarethabe4c5c92018-05-03 18:55:49 +0200222 @Test
223 public void testAuthorizeInvalidScope () throws KustvaktException {
margarethad67b4272022-04-11 17:34:19 +0200224 String scope = "read_address";
margarethad67b4272022-04-11 17:34:19 +0200225 ClientResponse response = requestAuthorizationCode("code",
226 confidentialClientId, "", scope, state, userAuthHeader);
margarethaffb89502022-04-20 12:03:16 +0200227 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
228 response.getStatus());
margarethabe4c5c92018-05-03 18:55:49 +0200229
margarethaffb89502022-04-20 12:03:16 +0200230 assertEquals(
231 "https://third.party.com/confidential/redirect?"
232 + "error_description=read_address+is+an+invalid+scope&"
233 + "state=thisIsMyState&error=invalid_scope",
234 response.getLocation().toString());
235 }
236
237 @Test
238 public void testAuthorizeUnsupportedTokenResponseType ()
239 throws KustvaktException {
240 ClientResponse response = requestAuthorizationCode("token",
241 confidentialClientId, "", "", state, userAuthHeader);
242 assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
243 response.getStatus());
244
245 assertEquals("https://third.party.com/confidential/redirect?"
246 + "error_description=response_type+token+is+not+"
247 + "supported&state=thisIsMyState&error=unsupported_"
248 + "response_type", response.getLocation().toString());
margarethabe4c5c92018-05-03 18:55:49 +0200249 }
250
margaretha6374f722018-04-17 18:45:57 +0200251 @Test
margarethaf0085122018-08-16 16:19:53 +0200252 public void testRequestTokenAuthorizationPublic ()
253 throws KustvaktException {
margarethad67b4272022-04-11 17:34:19 +0200254 String code =
255 requestAuthorizationCode(publicClientId, userAuthHeader);
margaretha835178d2018-08-15 19:04:03 +0200256
margarethaf0085122018-08-16 16:19:53 +0200257 ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
258 publicClientId, clientSecret, code);
margaretha835178d2018-08-15 19:04:03 +0200259 String entity = response.getEntity(String.class);
260 JsonNode node = JsonUtils.readTree(entity);
margarethaf0085122018-08-16 16:19:53 +0200261
margaretha835178d2018-08-15 19:04:03 +0200262 String accessToken = node.at("/access_token").asText();
margarethaf0085122018-08-16 16:19:53 +0200263
margaretha835178d2018-08-15 19:04:03 +0200264 assertEquals(TokenType.BEARER.toString(),
265 node.at("/token_type").asText());
margaretha0afd44a2020-02-05 10:49:21 +0100266 assertEquals(31536000, node.at("/expires_in").asInt());
margarethaf0085122018-08-16 16:19:53 +0200267
margaretha35074692021-03-26 18:11:59 +0100268 testRevokeToken(accessToken, publicClientId, null, ACCESS_TOKEN_TYPE);
margarethaf0085122018-08-16 16:19:53 +0200269
margaretha0afd44a2020-02-05 10:49:21 +0100270 assertTrue(node.at("/refresh_token").isMissingNode());
margaretha835178d2018-08-15 19:04:03 +0200271 }
margarethaf0085122018-08-16 16:19:53 +0200272
margaretha835178d2018-08-15 19:04:03 +0200273 @Test
margarethaa452c5e2018-04-25 22:48:09 +0200274 public void testRequestTokenAuthorizationConfidential ()
275 throws KustvaktException {
margarethabe4c5c92018-05-03 18:55:49 +0200276
margarethad67b4272022-04-11 17:34:19 +0200277 String scope = "search";
278 ClientResponse response = requestAuthorizationCode("code",
279 confidentialClientId, "", scope, state, userAuthHeader);
margarethabe4c5c92018-05-03 18:55:49 +0200280 MultivaluedMap<String, String> params =
margarethaffb89502022-04-20 12:03:16 +0200281 getQueryParamsFromURI(response.getLocation());
margarethabe4c5c92018-05-03 18:55:49 +0200282 String code = params.get("code").get(0);
283 String scopes = params.get("scope").get(0);
284
margaretha20f31232018-07-09 17:49:39 +0200285 assertEquals(scopes, "search");
margarethabe4c5c92018-05-03 18:55:49 +0200286
margarethaf0085122018-08-16 16:19:53 +0200287 response = requestTokenWithAuthorizationCodeAndForm(
288 confidentialClientId, clientSecret, code);
margarethaa452c5e2018-04-25 22:48:09 +0200289 String entity = response.getEntity(String.class);
290 JsonNode node = JsonUtils.readTree(entity);
291 assertNotNull(node.at("/access_token").asText());
292 assertNotNull(node.at("/refresh_token").asText());
293 assertEquals(TokenType.BEARER.toString(),
294 node.at("/token_type").asText());
295 assertNotNull(node.at("/expires_in").asText());
margarethabe4c5c92018-05-03 18:55:49 +0200296
margarethaf0085122018-08-16 16:19:53 +0200297 testRequestTokenWithUsedAuthorization(code);
margaretha35074692021-03-26 18:11:59 +0100298
margaretha6f0b7382018-11-21 17:42:02 +0100299 String refreshToken = node.at("/refresh_token").asText();
margaretha35074692021-03-26 18:11:59 +0100300
margaretha0afd44a2020-02-05 10:49:21 +0100301 testRequestRefreshTokenInvalidScope(confidentialClientId, refreshToken);
302 testRequestRefreshTokenInvalidClient(refreshToken);
303 testRequestRefreshTokenInvalidRefreshToken(confidentialClientId);
margaretha35074692021-03-26 18:11:59 +0100304
305 testRequestRefreshToken(confidentialClientId, clientSecret, refreshToken);
margarethaa452c5e2018-04-25 22:48:09 +0200306 }
margarethabe4c5c92018-05-03 18:55:49 +0200307
margarethaf0085122018-08-16 16:19:53 +0200308 private void testRequestTokenWithUsedAuthorization (String code)
309 throws KustvaktException {
310 ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
311 confidentialClientId, clientSecret, code);
margarethabe4c5c92018-05-03 18:55:49 +0200312 String entity = response.getEntity(String.class);
313
314 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
315
316 JsonNode node = JsonUtils.readTree(entity);
317 assertEquals(OAuthError.TokenResponse.INVALID_GRANT,
318 node.at("/error").asText());
319 assertEquals("Invalid authorization",
320 node.at("/error_description").asText());
321 }
322
323 @Test
324 public void testRequestTokenInvalidAuthorizationCode ()
325 throws KustvaktException {
margarethaf0085122018-08-16 16:19:53 +0200326 ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
327 confidentialClientId, clientSecret, "blahblah");
margarethabe4c5c92018-05-03 18:55:49 +0200328 String entity = response.getEntity(String.class);
329
330 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
331
332 JsonNode node = JsonUtils.readTree(entity);
333 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
334 node.at("/error").asText());
335 }
336
337 @Test
338 public void testRequestTokenAuthorizationReplyAttack ()
339 throws KustvaktException {
margarethad67b4272022-04-11 17:34:19 +0200340 String redirect_uri = "https://third.party.com/confidential/redirect";
341 String scope = "search";
margarethabe4c5c92018-05-03 18:55:49 +0200342
margarethaf0085122018-08-16 16:19:53 +0200343 ClientResponse response =
margarethad67b4272022-04-11 17:34:19 +0200344 requestAuthorizationCode("code", confidentialClientId,
345 redirect_uri, scope, state, userAuthHeader);
margarethabe4c5c92018-05-03 18:55:49 +0200346 MultivaluedMap<String, String> params =
margarethaffb89502022-04-20 12:03:16 +0200347 getQueryParamsFromURI(response.getLocation());
margarethabe4c5c92018-05-03 18:55:49 +0200348 String code = params.get("code").get(0);
349
350 testRequestTokenAuthorizationInvalidClient(code);
351 testRequestTokenAuthorizationInvalidRedirectUri(code);
margarethad67b4272022-04-11 17:34:19 +0200352 testRequestTokenAuthorizationRevoked(code, redirect_uri);
margarethabe4c5c92018-05-03 18:55:49 +0200353 }
354
355 private void testRequestTokenAuthorizationInvalidClient (String code)
356 throws KustvaktException {
margarethaf0085122018-08-16 16:19:53 +0200357 ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
358 confidentialClientId, "wrong_secret", code);
margarethabe4c5c92018-05-03 18:55:49 +0200359 String entity = response.getEntity(String.class);
360 JsonNode node = JsonUtils.readTree(entity);
361 assertEquals(OAuth2Error.INVALID_CLIENT, node.at("/error").asText());
362 }
363
364 private void testRequestTokenAuthorizationInvalidRedirectUri (String code)
365 throws KustvaktException {
366 MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
367 tokenForm.add("grant_type", "authorization_code");
margarethaf0085122018-08-16 16:19:53 +0200368 tokenForm.add("client_id", confidentialClientId);
margarethabe4c5c92018-05-03 18:55:49 +0200369 tokenForm.add("client_secret", "secret");
370 tokenForm.add("code", code);
371 tokenForm.add("redirect_uri", "https://blahblah.com");
372
373 ClientResponse response = requestToken(tokenForm);
374 String entity = response.getEntity(String.class);
375 JsonNode node = JsonUtils.readTree(entity);
376 assertEquals(OAuth2Error.INVALID_GRANT, node.at("/error").asText());
377 }
378
379 private void testRequestTokenAuthorizationRevoked (String code, String uri)
380 throws KustvaktException {
381 MultivaluedMap<String, String> tokenForm = new MultivaluedMapImpl();
382 tokenForm.add("grant_type", "authorization_code");
margarethaf0085122018-08-16 16:19:53 +0200383 tokenForm.add("client_id", confidentialClientId);
margarethabe4c5c92018-05-03 18:55:49 +0200384 tokenForm.add("client_secret", "secret");
385 tokenForm.add("code", code);
386 tokenForm.add("redirect_uri", uri);
387
388 ClientResponse response = requestToken(tokenForm);
389 String entity = response.getEntity(String.class);
390 JsonNode node = JsonUtils.readTree(entity);
391 assertEquals(OAuthError.TokenResponse.INVALID_GRANT,
392 node.at("/error").asText());
393 assertEquals("Invalid authorization",
394 node.at("/error_description").asText());
395 }
396
margarethaa452c5e2018-04-25 22:48:09 +0200397 @Test
margarethaf0085122018-08-16 16:19:53 +0200398 public void testRequestTokenPasswordGrantConfidentialSuper ()
margarethafb027f92018-04-23 20:00:13 +0200399 throws KustvaktException {
margarethaf0085122018-08-16 16:19:53 +0200400 ClientResponse response =
margaretha230effb2018-11-29 17:28:18 +0100401 requestTokenWithDoryPassword(superClientId, clientSecret);
margaretha6374f722018-04-17 18:45:57 +0200402
margarethaf0085122018-08-16 16:19:53 +0200403 assertEquals(Status.OK.getStatusCode(), response.getStatus());
404
margaretha6374f722018-04-17 18:45:57 +0200405 String entity = response.getEntity(String.class);
margaretha6374f722018-04-17 18:45:57 +0200406 JsonNode node = JsonUtils.readTree(entity);
407 assertNotNull(node.at("/access_token").asText());
margaretha6374f722018-04-17 18:45:57 +0200408 assertEquals(TokenType.BEARER.toString(),
409 node.at("/token_type").asText());
410 assertNotNull(node.at("/expires_in").asText());
margaretha35074692021-03-26 18:11:59 +0100411
margaretha93e602e2019-08-07 15:19:56 +0200412 RefreshToken refreshToken = refreshTokenDao
413 .retrieveRefreshToken(node.at("/refresh_token").asText());
414 Set<AccessScope> scopes = refreshToken.getScopes();
415 assertEquals(1, scopes.size());
416 assertEquals("[all]", scopes.toString());
margaretha6374f722018-04-17 18:45:57 +0200417 }
418
419 @Test
margarethaf0085122018-08-16 16:19:53 +0200420 public void testRequestTokenPasswordGrantConfidentialNonSuper ()
421 throws KustvaktException {
margaretha35074692021-03-26 18:11:59 +0100422 ClientResponse response = requestTokenWithDoryPassword(
423 confidentialClientId, clientSecret);
margarethaf0085122018-08-16 16:19:53 +0200424 String entity = response.getEntity(String.class);
425 assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
426
427 JsonNode node = JsonUtils.readTree(entity);
428 assertEquals(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT,
429 node.at("/error").asText());
430 assertEquals("Password grant is not allowed for third party clients",
431 node.at("/error_description").asText());
432 }
433
434 @Test
435 public void testRequestTokenPasswordGrantPublic ()
436 throws KustvaktException {
margaretha35074692021-03-26 18:11:59 +0100437 ClientResponse response =
438 requestTokenWithDoryPassword(publicClientId, "");
margarethaf0085122018-08-16 16:19:53 +0200439 String entity = response.getEntity(String.class);
440
441 assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
442
443 JsonNode node = JsonUtils.readTree(entity);
444 assertEquals(OAuth2Error.UNAUTHORIZED_CLIENT,
445 node.at("/error").asText());
446 assertEquals("Password grant is not allowed for third party clients",
447 node.at("/error_description").asText());
448 }
449
450 @Test
margaretha00c28c02018-07-05 18:09:09 +0200451 public void testRequestTokenPasswordGrantAuthorizationHeader ()
452 throws KustvaktException {
453 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
454 form.add("grant_type", "password");
margarethaf0085122018-08-16 16:19:53 +0200455 form.add("client_id", superClientId);
margaretha00c28c02018-07-05 18:09:09 +0200456 form.add("username", "dory");
457 form.add("password", "password");
458
margaretha35074692021-03-26 18:11:59 +0100459 ClientResponse response =
460 resource().path(API_VERSION).path("oauth2").path("token")
461 .header(HttpHeaders.AUTHORIZATION,
462 "Basic ZkNCYlFrQXlZekk0TnpVeE1nOnNlY3JldA==")
463 .header(HttpHeaders.CONTENT_TYPE,
464 ContentType.APPLICATION_FORM_URLENCODED)
465 .entity(form).post(ClientResponse.class);
margaretha00c28c02018-07-05 18:09:09 +0200466 String entity = response.getEntity(String.class);
margaretha00c28c02018-07-05 18:09:09 +0200467 JsonNode node = JsonUtils.readTree(entity);
468 assertNotNull(node.at("/access_token").asText());
469 assertNotNull(node.at("/refresh_token").asText());
470 assertEquals(TokenType.BEARER.toString(),
471 node.at("/token_type").asText());
472 assertNotNull(node.at("/expires_in").asText());
473 }
474
margaretha0a45be12018-07-12 15:06:30 +0200475 /**
476 * In case, client_id is specified both in Authorization header
477 * and request body, client_id in the request body is ignored.
478 *
479 * @throws KustvaktException
480 */
481 @Test
482 public void testRequestTokenPasswordGrantDifferentClientIds ()
483 throws KustvaktException {
484 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
485 form.add("grant_type", "password");
486 form.add("client_id", "9aHsGW6QflV13ixNpez");
487 form.add("username", "dory");
488 form.add("password", "password");
489
margaretha35074692021-03-26 18:11:59 +0100490 ClientResponse response =
491 resource().path(API_VERSION).path("oauth2").path("token")
492 .header(HttpHeaders.AUTHORIZATION,
493 "Basic ZkNCYlFrQXlZekk0TnpVeE1nOnNlY3JldA==")
494 .header(HttpHeaders.CONTENT_TYPE,
495 ContentType.APPLICATION_FORM_URLENCODED)
496 .entity(form).post(ClientResponse.class);
margaretha0a45be12018-07-12 15:06:30 +0200497 String entity = response.getEntity(String.class);
498 JsonNode node = JsonUtils.readTree(entity);
499 assertNotNull(node.at("/access_token").asText());
500 assertNotNull(node.at("/refresh_token").asText());
501 assertEquals(TokenType.BEARER.toString(),
502 node.at("/token_type").asText());
503 assertNotNull(node.at("/expires_in").asText());
504 }
505
margaretha00c28c02018-07-05 18:09:09 +0200506 @Test
margarethafb027f92018-04-23 20:00:13 +0200507 public void testRequestTokenPasswordGrantMissingClientSecret ()
508 throws KustvaktException {
margarethaf0085122018-08-16 16:19:53 +0200509 ClientResponse response =
margaretha230effb2018-11-29 17:28:18 +0100510 requestTokenWithDoryPassword(confidentialClientId, "");
margarethafb027f92018-04-23 20:00:13 +0200511 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
margaretha6374f722018-04-17 18:45:57 +0200512
513 String entity = response.getEntity(String.class);
514 JsonNode node = JsonUtils.readTree(entity);
margarethafb027f92018-04-23 20:00:13 +0200515 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
margaretha6374f722018-04-17 18:45:57 +0200516 node.at("/error").asText());
margarethafb027f92018-04-23 20:00:13 +0200517 assertEquals("Missing parameters: client_secret",
518 node.at("/error_description").asText());
margaretha6374f722018-04-17 18:45:57 +0200519 }
520
521 @Test
522 public void testRequestTokenPasswordGrantMissingClientId ()
margarethafb027f92018-04-23 20:00:13 +0200523 throws KustvaktException {
margaretha35074692021-03-26 18:11:59 +0100524 ClientResponse response =
525 requestTokenWithDoryPassword(null, clientSecret);
margaretha6374f722018-04-17 18:45:57 +0200526 String entity = response.getEntity(String.class);
527 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
528
529 JsonNode node = JsonUtils.readTree(entity);
530 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
531 node.at("/error").asText());
margarethafb027f92018-04-23 20:00:13 +0200532 assertEquals("Missing parameters: client_id",
margaretha6374f722018-04-17 18:45:57 +0200533 node.at("/error_description").asText());
534 }
margarethabe4c5c92018-05-03 18:55:49 +0200535
margarethafb027f92018-04-23 20:00:13 +0200536 @Test
margarethaf839dde2018-04-16 17:52:57 +0200537 public void testRequestTokenClientCredentialsGrant ()
margarethafb027f92018-04-23 20:00:13 +0200538 throws KustvaktException {
margarethaf839dde2018-04-16 17:52:57 +0200539
540 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
541 form.add("grant_type", "client_credentials");
margarethaf0085122018-08-16 16:19:53 +0200542 form.add("client_id", confidentialClientId);
margarethafb027f92018-04-23 20:00:13 +0200543 form.add("client_secret", "secret");
544 ClientResponse response = requestToken(form);
margarethaf839dde2018-04-16 17:52:57 +0200545 String entity = response.getEntity(String.class);
546 assertEquals(Status.OK.getStatusCode(), response.getStatus());
547
548 JsonNode node = JsonUtils.readTree(entity);
549 // length?
550 assertNotNull(node.at("/access_token").asText());
551 assertNotNull(node.at("/refresh_token").asText());
552 assertEquals(TokenType.BEARER.toString(),
553 node.at("/token_type").asText());
554 assertNotNull(node.at("/expires_in").asText());
555 }
556
margarethadc515072018-08-03 17:01:19 +0200557 /**
558 * Client credentials grant is only allowed for confidential
559 * clients.
560 */
561 @Test
562 public void testRequestTokenClientCredentialsGrantPublic ()
563 throws KustvaktException {
564
565 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
566 form.add("grant_type", "client_credentials");
margarethaf0085122018-08-16 16:19:53 +0200567 form.add("client_id", publicClientId);
margarethadc515072018-08-03 17:01:19 +0200568 form.add("client_secret", "");
569 ClientResponse response = requestToken(form);
570
571 String entity = response.getEntity(String.class);
572 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
573 JsonNode node = JsonUtils.readTree(entity);
574 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
575 node.at("/error").asText());
576 assertEquals("Missing parameters: client_secret",
577 node.at("/error_description").asText());
578 }
579
margarethaf839dde2018-04-16 17:52:57 +0200580 @Test
margarethabe4c5c92018-05-03 18:55:49 +0200581 public void testRequestTokenClientCredentialsGrantReducedScope ()
582 throws KustvaktException {
583
584 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
585 form.add("grant_type", "client_credentials");
margarethaf0085122018-08-16 16:19:53 +0200586 form.add("client_id", confidentialClientId);
margarethabe4c5c92018-05-03 18:55:49 +0200587 form.add("client_secret", "secret");
margaretha9c78e1a2018-06-27 14:12:35 +0200588 form.add("scope", "preferred_username client_info");
margarethabe4c5c92018-05-03 18:55:49 +0200589
590 ClientResponse response = requestToken(form);
591 String entity = response.getEntity(String.class);
592 assertEquals(Status.OK.getStatusCode(), response.getStatus());
593
594 JsonNode node = JsonUtils.readTree(entity);
595 // length?
596 assertNotNull(node.at("/access_token").asText());
597 assertNotNull(node.at("/refresh_token").asText());
598 assertEquals(TokenType.BEARER.toString(),
599 node.at("/token_type").asText());
600 assertNotNull(node.at("/expires_in").asText());
margaretha9c78e1a2018-06-27 14:12:35 +0200601 assertEquals("client_info", node.at("/scope").asText());
margarethabe4c5c92018-05-03 18:55:49 +0200602 }
603
604 @Test
margarethafb027f92018-04-23 20:00:13 +0200605 public void testRequestTokenMissingGrantType () throws KustvaktException {
margarethaf839dde2018-04-16 17:52:57 +0200606 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
margarethafb027f92018-04-23 20:00:13 +0200607 ClientResponse response = requestToken(form);
margarethaf839dde2018-04-16 17:52:57 +0200608 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
609
610 String entity = response.getEntity(String.class);
611 JsonNode node = JsonUtils.readTree(entity);
612 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
613 node.at("/error").asText());
614 }
margarethaa0486272018-04-12 19:59:31 +0200615
616 @Test
margarethafb027f92018-04-23 20:00:13 +0200617 public void testRequestTokenUnsupportedGrant () throws KustvaktException {
margarethaa0486272018-04-12 19:59:31 +0200618
619 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
margaretha05122312018-04-16 15:01:34 +0200620 form.add("grant_type", "blahblah");
621
margaretha35074692021-03-26 18:11:59 +0100622 ClientResponse response =
623 resource().path(API_VERSION).path("oauth2").path("token")
624 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
625 .header(HttpHeaders.CONTENT_TYPE,
626 ContentType.APPLICATION_FORM_URLENCODED)
627 .entity(form).post(ClientResponse.class);
margarethaa0486272018-04-12 19:59:31 +0200628
margaretha05122312018-04-16 15:01:34 +0200629 String entity = response.getEntity(String.class);
margaretha05122312018-04-16 15:01:34 +0200630 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
631
632 JsonNode node = JsonUtils.readTree(entity);
margarethaf839dde2018-04-16 17:52:57 +0200633 assertEquals("Invalid grant_type parameter value",
margaretha05122312018-04-16 15:01:34 +0200634 node.get("error_description").asText());
margarethaf839dde2018-04-16 17:52:57 +0200635 assertEquals(OAuthError.TokenResponse.INVALID_REQUEST,
636 node.get("error").asText());
margarethaa0486272018-04-12 19:59:31 +0200637 }
638
margaretha03b82862018-07-12 20:09:26 +0200639 private void testRequestRefreshTokenInvalidScope (String clientId,
640 String refreshToken) throws KustvaktException {
641 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
642 form.add("grant_type", GrantType.REFRESH_TOKEN.toString());
643 form.add("client_id", clientId);
margaretha0afd44a2020-02-05 10:49:21 +0100644 form.add("client_secret", clientSecret);
margaretha03b82862018-07-12 20:09:26 +0200645 form.add("refresh_token", refreshToken);
646 form.add("scope", "search serialize_query");
647
margaretha35074692021-03-26 18:11:59 +0100648 ClientResponse response =
649 resource().path(API_VERSION).path("oauth2").path("token")
650 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
651 .header(HttpHeaders.CONTENT_TYPE,
652 ContentType.APPLICATION_FORM_URLENCODED)
653 .entity(form).post(ClientResponse.class);
margaretha03b82862018-07-12 20:09:26 +0200654
655 String entity = response.getEntity(String.class);
656 JsonNode node = JsonUtils.readTree(entity);
657 assertEquals(OAuth2Error.INVALID_SCOPE, node.at("/error").asText());
658 }
659
margaretha35074692021-03-26 18:11:59 +0100660 private void testRequestRefreshToken (String clientId, String clientSecret,
margaretha03b82862018-07-12 20:09:26 +0200661 String refreshToken) throws KustvaktException {
662 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
663 form.add("grant_type", GrantType.REFRESH_TOKEN.toString());
664 form.add("client_id", clientId);
margaretha35074692021-03-26 18:11:59 +0100665 form.add("client_secret", clientSecret);
margaretha03b82862018-07-12 20:09:26 +0200666 form.add("refresh_token", refreshToken);
667
margaretha35074692021-03-26 18:11:59 +0100668 ClientResponse response =
669 resource().path(API_VERSION).path("oauth2").path("token")
670 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
671 .header(HttpHeaders.CONTENT_TYPE,
672 ContentType.APPLICATION_FORM_URLENCODED)
673 .entity(form).post(ClientResponse.class);
margaretha03b82862018-07-12 20:09:26 +0200674
675 String entity = response.getEntity(String.class);
676 assertEquals(Status.OK.getStatusCode(), response.getStatus());
677
678 JsonNode node = JsonUtils.readTree(entity);
679 assertNotNull(node.at("/access_token").asText());
margaretha35074692021-03-26 18:11:59 +0100680
681 String newRefreshToken = node.at("/refresh_token").asText();
682 assertNotNull(newRefreshToken);
margaretha03b82862018-07-12 20:09:26 +0200683 assertEquals(TokenType.BEARER.toString(),
684 node.at("/token_type").asText());
685 assertNotNull(node.at("/expires_in").asText());
margaretha6f0b7382018-11-21 17:42:02 +0100686
margaretha35074692021-03-26 18:11:59 +0100687 assertTrue(!newRefreshToken.equals(refreshToken));
margaretha93e602e2019-08-07 15:19:56 +0200688
margaretha35074692021-03-26 18:11:59 +0100689 testRequestTokenWithRevokedRefreshToken(clientId, clientSecret,
690 refreshToken);
691
692 testRevokeToken(newRefreshToken, clientId, clientSecret,
693 REFRESH_TOKEN_TYPE);
694 testRequestTokenWithRevokedRefreshToken(clientId, clientSecret,
695 newRefreshToken);
margaretha03b82862018-07-12 20:09:26 +0200696 }
697
698 private void testRequestRefreshTokenInvalidClient (String refreshToken)
699 throws KustvaktException {
700 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
701 form.add("grant_type", GrantType.REFRESH_TOKEN.toString());
margaretha835178d2018-08-15 19:04:03 +0200702 form.add("client_id", "iBr3LsTCxOj7D2o0A5m");
margaretha03b82862018-07-12 20:09:26 +0200703 form.add("refresh_token", refreshToken);
704
margaretha35074692021-03-26 18:11:59 +0100705 ClientResponse response =
706 resource().path(API_VERSION).path("oauth2").path("token")
707 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
708 .header(HttpHeaders.CONTENT_TYPE,
709 ContentType.APPLICATION_FORM_URLENCODED)
710 .entity(form).post(ClientResponse.class);
margaretha03b82862018-07-12 20:09:26 +0200711
712 String entity = response.getEntity(String.class);
713 JsonNode node = JsonUtils.readTree(entity);
714 assertEquals(OAuth2Error.INVALID_CLIENT, node.at("/error").asText());
715 }
716
717 private void testRequestRefreshTokenInvalidRefreshToken (String clientId)
718 throws KustvaktException {
719 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
720 form.add("grant_type", GrantType.REFRESH_TOKEN.toString());
721 form.add("client_id", clientId);
margaretha0afd44a2020-02-05 10:49:21 +0100722 form.add("client_secret", clientSecret);
margaretha03b82862018-07-12 20:09:26 +0200723 form.add("refresh_token", "Lia8s8w8tJeZSBlaQDrYV8ion3l");
724
margaretha35074692021-03-26 18:11:59 +0100725 ClientResponse response =
726 resource().path(API_VERSION).path("oauth2").path("token")
727 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
728 .header(HttpHeaders.CONTENT_TYPE,
729 ContentType.APPLICATION_FORM_URLENCODED)
730 .entity(form).post(ClientResponse.class);
margaretha03b82862018-07-12 20:09:26 +0200731
732 String entity = response.getEntity(String.class);
733 JsonNode node = JsonUtils.readTree(entity);
734 assertEquals(OAuth2Error.INVALID_GRANT, node.at("/error").asText());
735 }
736
margaretha35074692021-03-26 18:11:59 +0100737 private JsonNode requestTokenList (String userAuthHeader, String tokenType,
738 String clientId) throws KustvaktException {
739 MultivaluedMap<String, String> form = new MultivaluedMapImpl();
740 form.add("super_client_id", superClientId);
741 form.add("super_client_secret", clientSecret);
742 form.add("token_type", tokenType);
743
744 if (clientId != null && !clientId.isEmpty()){
745 form.add("client_id", clientId);
746 }
747
748 ClientResponse response = resource().path(API_VERSION).path("oauth2")
749 .path("token").path("list")
750 .header(Attributes.AUTHORIZATION, userAuthHeader)
margarethadc515072018-08-03 17:01:19 +0200751 .header(HttpHeaders.CONTENT_TYPE,
752 ContentType.APPLICATION_FORM_URLENCODED)
753 .entity(form).post(ClientResponse.class);
margarethaf0085122018-08-16 16:19:53 +0200754
margarethadc515072018-08-03 17:01:19 +0200755 assertEquals(Status.OK.getStatusCode(), response.getStatus());
margaretha35074692021-03-26 18:11:59 +0100756
757 String entity = response.getEntity(String.class);
758 return JsonUtils.readTree(entity);
759 }
760
761 private JsonNode requestTokenList (String userAuthHeader, String tokenType)
762 throws KustvaktException {
763 return requestTokenList(userAuthHeader, tokenType, null);
margaretha7497adf2019-11-26 13:13:57 +0100764 }
765
margaretha43aceb52019-11-21 12:58:53 +0100766 @Test
margaretha35074692021-03-26 18:11:59 +0100767 public void testListRefreshTokenConfidentialClient () throws KustvaktException {
margaretha43aceb52019-11-21 12:58:53 +0100768 String username = "gurgle";
769 String password = "pwd";
770 userAuthHeader = HttpAuthorizationHandler
771 .createBasicAuthorizationHeaderValue(username, password);
772
773 // super client
774 ClientResponse response = requestTokenWithPassword(superClientId,
775 clientSecret, username, password);
776 assertEquals(Status.OK.getStatusCode(), response.getStatus());
777 JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
778 String refreshToken1 = node.at("/refresh_token").asText();
779
780 // client 1
margarethad67b4272022-04-11 17:34:19 +0200781 String code =
782 requestAuthorizationCode(confidentialClientId, userAuthHeader);
margaretha0afd44a2020-02-05 10:49:21 +0100783 response = requestTokenWithAuthorizationCodeAndForm(
784 confidentialClientId, clientSecret, code);
margaretha43aceb52019-11-21 12:58:53 +0100785 assertEquals(Status.OK.getStatusCode(), response.getStatus());
786
787 // client 2
margarethad67b4272022-04-11 17:34:19 +0200788 code = requestAuthorizationCode(confidentialClientId2,
789 clientRedirectUri, userAuthHeader);
margaretha0afd44a2020-02-05 10:49:21 +0100790 response = requestTokenWithAuthorizationCodeAndForm(
margarethad67b4272022-04-11 17:34:19 +0200791 confidentialClientId2, clientSecret, code, clientRedirectUri);
margaretha0afd44a2020-02-05 10:49:21 +0100792 assertEquals(Status.OK.getStatusCode(), response.getStatus());
793
794 // list
margaretha35074692021-03-26 18:11:59 +0100795 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE);
margaretha0afd44a2020-02-05 10:49:21 +0100796 assertEquals(2, node.size());
margaretha4f4b9ab2021-04-30 17:33:21 +0200797 assertEquals(confidentialClientId, node.at("/0/client_id").asText());
798 assertEquals(confidentialClientId2, node.at("/1/client_id").asText());
margaretha35074692021-03-26 18:11:59 +0100799
margaretha0afd44a2020-02-05 10:49:21 +0100800 // client 1
margarethad67b4272022-04-11 17:34:19 +0200801 code = requestAuthorizationCode(confidentialClientId, userAuthHeader);
margaretha43aceb52019-11-21 12:58:53 +0100802 response = requestTokenWithAuthorizationCodeAndForm(
803 confidentialClientId, clientSecret, code);
804 assertEquals(Status.OK.getStatusCode(), response.getStatus());
805
margaretha7497adf2019-11-26 13:13:57 +0100806 // another user
807 String darlaAuthHeader = HttpAuthorizationHandler
808 .createBasicAuthorizationHeaderValue("darla", "pwd");
margaretha35074692021-03-26 18:11:59 +0100809
810 // test listing clients
811 node = requestTokenList(darlaAuthHeader, REFRESH_TOKEN_TYPE);
812 assertEquals(0, node.size());
813
margaretha43aceb52019-11-21 12:58:53 +0100814 // client 1
margarethad67b4272022-04-11 17:34:19 +0200815 code = requestAuthorizationCode(confidentialClientId, darlaAuthHeader);
margaretha43aceb52019-11-21 12:58:53 +0100816 assertEquals(Status.OK.getStatusCode(), response.getStatus());
817 response = requestTokenWithAuthorizationCodeAndForm(
margaretha0afd44a2020-02-05 10:49:21 +0100818 confidentialClientId, clientSecret, code);
margaretha35074692021-03-26 18:11:59 +0100819
margaretha43aceb52019-11-21 12:58:53 +0100820 node = JsonUtils.readTree(response.getEntity(String.class));
821 String refreshToken5 = node.at("/refresh_token").asText();
margaretha35074692021-03-26 18:11:59 +0100822
823 // list all refresh tokens
824 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE);
margaretha43aceb52019-11-21 12:58:53 +0100825 assertEquals(3, node.size());
margaretha35074692021-03-26 18:11:59 +0100826
827 // list refresh tokens from client 1
828 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE, confidentialClientId);
829 assertEquals(2, node.size());
margaretha43aceb52019-11-21 12:58:53 +0100830
831 testRevokeToken(refreshToken1, superClientId, clientSecret,
832 REFRESH_TOKEN_TYPE);
margaretha35074692021-03-26 18:11:59 +0100833 testRevokeToken(node.at("/0/token").asText(), confidentialClientId,
margaretha0afd44a2020-02-05 10:49:21 +0100834 clientSecret, REFRESH_TOKEN_TYPE);
835 testRevokeToken(node.at("/1/token").asText(), confidentialClientId2,
margaretha43aceb52019-11-21 12:58:53 +0100836 clientSecret, REFRESH_TOKEN_TYPE);
margaretha35074692021-03-26 18:11:59 +0100837
838 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE);
margaretha43aceb52019-11-21 12:58:53 +0100839 assertEquals(1, node.size());
margaretha35074692021-03-26 18:11:59 +0100840
841 testRevokeTokenViaSuperClient(node.at("/0/token").asText(),
842 userAuthHeader);
843 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE);
margaretha7497adf2019-11-26 13:13:57 +0100844 assertEquals(0, node.size());
margaretha35074692021-03-26 18:11:59 +0100845
margaretha7497adf2019-11-26 13:13:57 +0100846 // try revoking a token belonging to another user
847 // should not return any errors
848 testRevokeTokenViaSuperClient(refreshToken5, userAuthHeader);
margaretha35074692021-03-26 18:11:59 +0100849 node = requestTokenList(darlaAuthHeader, REFRESH_TOKEN_TYPE);
margaretha7497adf2019-11-26 13:13:57 +0100850 assertEquals(1, node.size());
margaretha35074692021-03-26 18:11:59 +0100851
margaretha7497adf2019-11-26 13:13:57 +0100852 testRevokeTokenViaSuperClient(refreshToken5, darlaAuthHeader);
margaretha35074692021-03-26 18:11:59 +0100853 node = requestTokenList(darlaAuthHeader, REFRESH_TOKEN_TYPE);
margaretha7497adf2019-11-26 13:13:57 +0100854 assertEquals(0, node.size());
margaretha43aceb52019-11-21 12:58:53 +0100855 }
margaretha43aceb52019-11-21 12:58:53 +0100856
margaretha43aceb52019-11-21 12:58:53 +0100857
margaretha35074692021-03-26 18:11:59 +0100858 @Test
859 public void testListTokenPublicClient () throws KustvaktException {
860 String username = "nemo";
861 String password = "pwd";
862 userAuthHeader = HttpAuthorizationHandler
863 .createBasicAuthorizationHeaderValue(username, password);
864
865 // access token 1
margarethad67b4272022-04-11 17:34:19 +0200866 String code = requestAuthorizationCode(publicClientId, userAuthHeader);
margaretha35074692021-03-26 18:11:59 +0100867 ClientResponse response = requestTokenWithAuthorizationCodeAndForm(publicClientId, "",
868 code);
margaretha43aceb52019-11-21 12:58:53 +0100869 assertEquals(Status.OK.getStatusCode(), response.getStatus());
margaretha35074692021-03-26 18:11:59 +0100870 JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
871 String accessToken1 = node.at("/access_token").asText();
margaretha43aceb52019-11-21 12:58:53 +0100872
margaretha35074692021-03-26 18:11:59 +0100873 // access token 2
margarethad67b4272022-04-11 17:34:19 +0200874 code = requestAuthorizationCode(publicClientId, userAuthHeader);
margaretha35074692021-03-26 18:11:59 +0100875 response = requestTokenWithAuthorizationCodeAndForm(publicClientId, "",
876 code);
877 assertEquals(Status.OK.getStatusCode(), response.getStatus());
878 node = JsonUtils.readTree(response.getEntity(String.class));
879 String accessToken2 = node.at("/access_token").asText();
880
881 // list access tokens
882 node = requestTokenList(userAuthHeader, ACCESS_TOKEN_TYPE);
883 assertEquals(2, node.size());
884
885 // list refresh tokens
886 node = requestTokenList(userAuthHeader, REFRESH_TOKEN_TYPE);
887 assertEquals(0, node.size());
888
889 testRevokeTokenViaSuperClient(accessToken1, userAuthHeader);
890 node = requestTokenList(userAuthHeader, ACCESS_TOKEN_TYPE);
margarethab250ddc2021-06-07 12:07:17 +0200891// System.out.println(node);
margaretha35074692021-03-26 18:11:59 +0100892 assertEquals(1, node.size());
margaretha4f4b9ab2021-04-30 17:33:21 +0200893 assertEquals(accessToken2, node.at("/0/token").asText());
894 assertTrue(node.at("/0/scope").size()>0);
895 assertNotNull(node.at("/0/created_date").asText());
896 assertNotNull(node.at("/0/expires_in").asLong());
897 assertNotNull(node.at("/0/user_authentication_time").asText());
898
899 assertEquals(publicClientId, node.at("/0/client_id").asText());
900 assertNotNull(node.at("/0/client_name").asText());
901 assertNotNull(node.at("/0/client_description").asText());
902 assertNotNull(node.at("/0/client_url").asText());
903
margaretha35074692021-03-26 18:11:59 +0100904
905 testRevokeTokenViaSuperClient(accessToken2, userAuthHeader);
906 node = requestTokenList(userAuthHeader, ACCESS_TOKEN_TYPE);
907 assertEquals(0, node.size());
margaretha43aceb52019-11-21 12:58:53 +0100908 }
margarethaa0486272018-04-12 19:59:31 +0200909}