| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 1 | package de.ids_mannheim.korap.web.controller; |
| 2 | |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 4 | import static org.junit.jupiter.api.Assertions.assertNotNull; |
| 5 | import static org.junit.jupiter.api.Assertions.assertTrue; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 6 | |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 7 | import java.io.IOException; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 8 | |
| margaretha | 96c309d | 2023-08-16 12:24:12 +0200 | [diff] [blame] | 9 | import jakarta.ws.rs.client.Entity; |
| 10 | import jakarta.ws.rs.core.Form; |
| 11 | import jakarta.ws.rs.core.Response; |
| 12 | import jakarta.ws.rs.core.Response.Status; |
| margaretha | b1081b1 | 2018-07-03 23:35:01 +0200 | [diff] [blame] | 13 | |
| 14 | import org.apache.http.entity.ContentType; |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 15 | import org.junit.jupiter.api.Test; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 16 | import com.fasterxml.jackson.databind.JsonNode; |
| 17 | import com.google.common.net.HttpHeaders; |
| margaretha | 53c1ff8 | 2023-10-26 12:33:26 +0200 | [diff] [blame] | 18 | import com.nimbusds.oauth2.sdk.GrantType; |
| 19 | |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 20 | import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 21 | import de.ids_mannheim.korap.config.Attributes; |
| margaretha | 2df0660 | 2018-11-14 19:10:30 +0100 | [diff] [blame] | 22 | import de.ids_mannheim.korap.constant.OAuth2Scope; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 23 | import de.ids_mannheim.korap.constant.TokenType; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 24 | import de.ids_mannheim.korap.exceptions.KustvaktException; |
| 25 | import de.ids_mannheim.korap.exceptions.StatusCodes; |
| 26 | import de.ids_mannheim.korap.utils.JsonUtils; |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 27 | import de.ids_mannheim.korap.web.controller.usergroup.UserGroupTestBase; |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 28 | |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 29 | public class OAuth2AccessTokenTest extends UserGroupTestBase { |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 30 | |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 31 | private String userAuthHeader; |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 32 | |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 33 | private String clientAuthHeader; |
| margaretha | 1ef36bd | 2018-08-14 18:17:05 +0200 | [diff] [blame] | 34 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 35 | public OAuth2AccessTokenTest () throws KustvaktException { |
| 36 | userAuthHeader = HttpAuthorizationHandler |
| 37 | .createBasicAuthorizationHeaderValue("dory", "password"); |
| 38 | clientAuthHeader = HttpAuthorizationHandler |
| 39 | .createBasicAuthorizationHeaderValue(confidentialClientId, |
| 40 | clientSecret); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 41 | } |
| margaretha | 064eb6f | 2018-07-10 18:33:01 +0200 | [diff] [blame] | 42 | |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 43 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 44 | public void testScopeWithSuperClient () throws KustvaktException { |
| 45 | Response response = requestTokenWithDoryPassword(superClientId, |
| 46 | clientSecret); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 47 | JsonNode node = JsonUtils.readTree(response.readEntity(String.class)); |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 48 | assertEquals(node.at("/scope").asText(), "all"); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 49 | String accessToken = node.at("/access_token").asText(); |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 50 | |
| 51 | createDoryGroup(); |
| 52 | createMarlinGroup(); |
| margaretha | 0483671 | 2024-08-16 13:03:56 +0200 | [diff] [blame^] | 53 | addMember(marlinGroupName, "dory", "marlin"); |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 54 | |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 55 | // test list user group |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 56 | response = target().path(API_VERSION).path("group").request() |
| 57 | .header(Attributes.AUTHORIZATION, "Bearer " + accessToken) |
| 58 | .get(); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 59 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 60 | node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 61 | assertEquals(2, node.size()); |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 62 | |
| 63 | deleteGroupByName(doryGroupName, "dory"); |
| 64 | deleteGroupByName(marlinGroupName, "marlin"); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 68 | public void testCustomScope () throws KustvaktException { |
| 69 | Response response = requestAuthorizationCode("code", |
| 70 | confidentialClientId, "", OAuth2Scope.VC_INFO.toString(), "", |
| 71 | userAuthHeader); |
| margaretha | 6345b81 | 2023-05-02 15:03:06 +0200 | [diff] [blame] | 72 | String code = parseAuthorizationCode(response); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 73 | response = requestTokenWithAuthorizationCodeAndForm( |
| 74 | confidentialClientId, clientSecret, code); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 75 | JsonNode node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 76 | String token = node.at("/access_token").asText(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 77 | assertTrue(node.at("/scope").asText() |
| 78 | .contains(OAuth2Scope.VC_INFO.toString())); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 79 | // test list vc using the token |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 80 | response = target().path(API_VERSION).path("vc").request() |
| 81 | .header(Attributes.AUTHORIZATION, "Bearer " + token).get(); |
| margaretha | 20f3123 | 2018-07-09 17:49:39 +0200 | [diff] [blame] | 82 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 83 | node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | d001770 | 2024-07-29 13:13:43 +0200 | [diff] [blame] | 84 | assertEquals(3, node.size()); |
| margaretha | 20f3123 | 2018-07-09 17:49:39 +0200 | [diff] [blame] | 85 | } |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 86 | |
| 87 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 88 | public void testDefaultScope () throws KustvaktException, IOException { |
| 89 | String code = requestAuthorizationCode(confidentialClientId, |
| 90 | userAuthHeader); |
| 91 | Response response = requestTokenWithAuthorizationCodeAndForm( |
| 92 | confidentialClientId, clientSecret, code); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 93 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 94 | JsonNode node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 95 | String accessToken = node.at("/access_token").asText(); |
| 96 | testScopeNotAuthorized(accessToken); |
| 97 | testScopeNotAuthorize2(accessToken); |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 98 | testSearchWithOAuth2Token(accessToken); |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 99 | } |
| 100 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 101 | private void testScopeNotAuthorized (String accessToken) |
| 102 | throws KustvaktException { |
| 103 | Response response = target().path(API_VERSION).path("vc").request() |
| 104 | .header(Attributes.AUTHORIZATION, "Bearer " + accessToken) |
| 105 | .get(); |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 106 | assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 107 | String entity = response.readEntity(String.class); |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 108 | JsonNode node = JsonUtils.readTree(entity); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 109 | assertEquals(StatusCodes.AUTHORIZATION_FAILED, |
| 110 | node.at("/errors/0/0").asInt()); |
| 111 | assertEquals(node.at("/errors/0/1").asText(), |
| 112 | "Scope vc_info is not authorized"); |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 113 | } |
| 114 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 115 | private void testScopeNotAuthorize2 (String accessToken) |
| 116 | throws KustvaktException { |
| 117 | Response response = target().path(API_VERSION).path("vc").path("access") |
| 118 | .request() |
| 119 | .header(Attributes.AUTHORIZATION, "Bearer " + accessToken) |
| 120 | .get(); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 121 | String entity = response.readEntity(String.class); |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 122 | assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); |
| margaretha | 0a45be1 | 2018-07-12 15:06:30 +0200 | [diff] [blame] | 123 | JsonNode node = JsonUtils.readTree(entity); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 124 | assertEquals(StatusCodes.AUTHORIZATION_FAILED, |
| 125 | node.at("/errors/0/0").asInt()); |
| 126 | assertEquals(node.at("/errors/0/1").asText(), |
| 127 | "Scope vc_access_info is not authorized"); |
| margaretha | 0a45be1 | 2018-07-12 15:06:30 +0200 | [diff] [blame] | 128 | } |
| 129 | |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 130 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 131 | public void testSearchWithUnknownToken () |
| 132 | throws KustvaktException, IOException { |
| 133 | Response response = searchWithAccessToken( |
| 134 | "ljsa8tKNRSczJhk20öhq92zG8z350"); |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 135 | assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 136 | String ent = response.readEntity(String.class); |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 137 | JsonNode node = JsonUtils.readTree(ent); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 138 | assertEquals(StatusCodes.INVALID_ACCESS_TOKEN, |
| 139 | node.at("/errors/0/0").asInt()); |
| 140 | assertEquals(node.at("/errors/0/1").asText(), |
| 141 | "Access token is invalid"); |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 142 | } |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 143 | |
| 144 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 145 | public void testRevokeAccessTokenConfidentialClient () |
| 146 | throws KustvaktException { |
| 147 | String code = requestAuthorizationCode(confidentialClientId, |
| 148 | userAuthHeader); |
| 149 | JsonNode node = requestTokenWithAuthorizationCodeAndHeader( |
| 150 | confidentialClientId, code, clientAuthHeader); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 151 | String accessToken = node.at("/access_token").asText(); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 152 | Form form = new Form(); |
| 153 | form.param("token", accessToken); |
| 154 | form.param("client_id", confidentialClientId); |
| 155 | form.param("client_secret", "secret"); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 156 | Response response = target().path(API_VERSION).path("oauth2") |
| 157 | .path("revoke").request() |
| 158 | .header(HttpHeaders.CONTENT_TYPE, |
| 159 | ContentType.APPLICATION_FORM_URLENCODED) |
| 160 | .post(Entity.form(form)); |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 161 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 162 | testSearchWithRevokedAccessToken(accessToken); |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 163 | } |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 164 | |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 165 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 166 | public void testRevokeAccessTokenPublicClientViaSuperClient () |
| 167 | throws KustvaktException { |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 168 | String code = requestAuthorizationCode(publicClientId, userAuthHeader); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 169 | Response response = requestTokenWithAuthorizationCodeAndForm( |
| 170 | publicClientId, "", code); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 171 | JsonNode node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 172 | String accessToken = node.at("/access_token").asText(); |
| 173 | testRevokeTokenViaSuperClient(accessToken, userAuthHeader); |
| 174 | testSearchWithRevokedAccessToken(accessToken); |
| 175 | } |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 176 | |
| margaretha | 1ef36bd | 2018-08-14 18:17:05 +0200 | [diff] [blame] | 177 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 178 | public void testAccessTokenAfterRequestRefreshToken () |
| 179 | throws KustvaktException, IOException { |
| 180 | String code = requestAuthorizationCode(confidentialClientId, |
| 181 | userAuthHeader); |
| 182 | JsonNode node = requestTokenWithAuthorizationCodeAndHeader( |
| 183 | confidentialClientId, code, clientAuthHeader); |
| margaretha | 1ef36bd | 2018-08-14 18:17:05 +0200 | [diff] [blame] | 184 | String accessToken = node.at("/access_token").asText(); |
| 185 | String refreshToken = node.at("/refresh_token").asText(); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 186 | Form form = new Form(); |
| 187 | form.param("grant_type", GrantType.REFRESH_TOKEN.toString()); |
| 188 | form.param("client_id", confidentialClientId); |
| 189 | form.param("client_secret", "secret"); |
| 190 | form.param("refresh_token", refreshToken); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 191 | Response response = target().path(API_VERSION).path("oauth2") |
| 192 | .path("token").request() |
| 193 | .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32") |
| 194 | .header(HttpHeaders.CONTENT_TYPE, |
| 195 | ContentType.APPLICATION_FORM_URLENCODED) |
| 196 | .post(Entity.form(form)); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 197 | String entity = response.readEntity(String.class); |
| margaretha | 1ef36bd | 2018-08-14 18:17:05 +0200 | [diff] [blame] | 198 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| margaretha | 1ef36bd | 2018-08-14 18:17:05 +0200 | [diff] [blame] | 199 | node = JsonUtils.readTree(entity); |
| 200 | assertNotNull(node.at("/access_token").asText()); |
| margaretha | 6f0b738 | 2018-11-21 17:42:02 +0100 | [diff] [blame] | 201 | assertTrue(!refreshToken.equals(node.at("/refresh_token").asText())); |
| margaretha | 6f0b738 | 2018-11-21 17:42:02 +0100 | [diff] [blame] | 202 | testSearchWithRevokedAccessToken(accessToken); |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 203 | } |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 204 | |
| 205 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 206 | public void testRequestAuthorizationWithBearerTokenUnauthorized () |
| 207 | throws KustvaktException { |
| 208 | String code = requestAuthorizationCode(confidentialClientId, |
| 209 | userAuthHeader); |
| 210 | JsonNode node = requestTokenWithAuthorizationCodeAndHeader( |
| 211 | confidentialClientId, code, clientAuthHeader); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 212 | String userAuthToken = node.at("/access_token").asText(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 213 | Response response = requestAuthorizationCode("code", |
| 214 | confidentialClientId, "", "search", "", |
| 215 | "Bearer " + userAuthToken); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 216 | assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 217 | node = JsonUtils.readTree(response.readEntity(String.class)); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 218 | assertEquals(StatusCodes.AUTHORIZATION_FAILED, |
| 219 | node.at("/errors/0/0").asInt()); |
| 220 | assertEquals(node.at("/errors/0/1").asText(), |
| 221 | "Scope authorize is not authorized"); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 222 | } |
| 223 | |
| 224 | @Test |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 225 | public void testRequestAuthorizationWithBearerToken () |
| 226 | throws KustvaktException { |
| 227 | Response response = requestTokenWithDoryPassword(superClientId, |
| 228 | clientSecret); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 229 | String entity = response.readEntity(String.class); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 230 | JsonNode node = JsonUtils.readTree(entity); |
| 231 | String userAuthToken = node.at("/access_token").asText(); |
| 232 | assertNotNull(userAuthToken); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 233 | assertEquals(TokenType.BEARER.displayName(), |
| 234 | node.at("/token_type").asText()); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 235 | assertNotNull(node.at("/expires_in").asText()); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 236 | String code = requestAuthorizationCode(superClientId, |
| 237 | "Bearer " + userAuthToken); |
| margaretha | 835178d | 2018-08-15 19:04:03 +0200 | [diff] [blame] | 238 | assertNotNull(code); |
| 239 | } |
| margaretha | cf306d3 | 2018-05-30 19:45:35 +0200 | [diff] [blame] | 240 | } |