| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 1 | package de.ids_mannheim.korap.web.controller; |
| 2 | |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 3 | import java.io.IOException; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 4 | import java.net.URI; |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 5 | import java.time.ZoneId; |
| 6 | import java.time.ZonedDateTime; |
| 7 | import java.util.HashSet; |
| 8 | import java.util.Set; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 9 | |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 10 | import org.apache.http.entity.ContentType; |
| margaretha | cc92959 | 2023-01-31 11:07:35 +0100 | [diff] [blame] | 11 | import org.glassfish.jersey.client.ClientConfig; |
| 12 | import org.glassfish.jersey.client.ClientProperties; |
| margaretha | b22a585 | 2023-01-27 14:43:36 +0100 | [diff] [blame] | 13 | import org.glassfish.jersey.uri.UriComponent; |
| margaretha | 93e602e | 2019-08-07 15:19:56 +0200 | [diff] [blame] | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 15 | import org.springframework.util.MultiValueMap; |
| 16 | import org.springframework.web.util.UriComponentsBuilder; |
| 17 | |
| 18 | import com.fasterxml.jackson.databind.JsonNode; |
| 19 | import com.google.common.net.HttpHeaders; |
| margaretha | 53c1ff8 | 2023-10-26 12:33:26 +0200 | [diff] [blame] | 20 | import com.nimbusds.oauth2.sdk.GrantType; |
| margaretha | 5f5d3ed | 2023-08-30 23:48:52 +0200 | [diff] [blame] | 21 | import com.nimbusds.oauth2.sdk.OAuth2Error; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 22 | |
| 23 | import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler; |
| 24 | import de.ids_mannheim.korap.config.Attributes; |
| 25 | import de.ids_mannheim.korap.config.SpringJerseyTest; |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 26 | import de.ids_mannheim.korap.constant.OAuth2Scope; |
| 27 | import de.ids_mannheim.korap.encryption.RandomCodeGenerator; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 28 | import de.ids_mannheim.korap.exceptions.KustvaktException; |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 29 | import de.ids_mannheim.korap.exceptions.StatusCodes; |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 30 | import de.ids_mannheim.korap.oauth2.constant.OAuth2ClientType; |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 31 | import de.ids_mannheim.korap.oauth2.dao.AccessTokenDao; |
| 32 | import de.ids_mannheim.korap.oauth2.dao.OAuth2ClientDao; |
| margaretha | 93e602e | 2019-08-07 15:19:56 +0200 | [diff] [blame] | 33 | import de.ids_mannheim.korap.oauth2.dao.RefreshTokenDao; |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 34 | import de.ids_mannheim.korap.oauth2.entity.AccessScope; |
| 35 | import de.ids_mannheim.korap.oauth2.entity.AccessToken; |
| 36 | import de.ids_mannheim.korap.oauth2.entity.OAuth2Client; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 37 | import de.ids_mannheim.korap.utils.JsonUtils; |
| margaretha | 977fabe | 2022-04-28 09:23:47 +0200 | [diff] [blame] | 38 | import de.ids_mannheim.korap.utils.TimeUtils; |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 39 | import de.ids_mannheim.korap.web.input.OAuth2ClientJson; |
| margaretha | 96c309d | 2023-08-16 12:24:12 +0200 | [diff] [blame] | 40 | import jakarta.ws.rs.ProcessingException; |
| 41 | import jakarta.ws.rs.client.Client; |
| 42 | import jakarta.ws.rs.client.ClientBuilder; |
| 43 | import jakarta.ws.rs.client.Entity; |
| margaretha | 5f5d3ed | 2023-08-30 23:48:52 +0200 | [diff] [blame] | 44 | import jakarta.ws.rs.client.Invocation.Builder; |
| margaretha | 96c309d | 2023-08-16 12:24:12 +0200 | [diff] [blame] | 45 | import jakarta.ws.rs.client.WebTarget; |
| 46 | import jakarta.ws.rs.core.Form; |
| 47 | import jakarta.ws.rs.core.MultivaluedMap; |
| 48 | import jakarta.ws.rs.core.Response; |
| 49 | import jakarta.ws.rs.core.Response.Status; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 50 | |
| Marc Kupietz | d43a98d | 2023-09-22 17:11:46 +0200 | [diff] [blame] | 51 | import static org.junit.jupiter.api.Assertions.*; |
| 52 | |
| margaretha | 230effb | 2018-11-29 17:28:18 +0100 | [diff] [blame] | 53 | /** |
| 54 | * Provides common methods and variables for OAuth2 tests, |
| 55 | * and does not run any test. |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 56 | * |
| 57 | * @author margaretha |
| 58 | * |
| 59 | */ |
| margaretha | f370f54 | 2018-08-23 18:51:49 +0200 | [diff] [blame] | 60 | public abstract class OAuth2TestBase extends SpringJerseyTest { |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 61 | |
| margaretha | 93e602e | 2019-08-07 15:19:56 +0200 | [diff] [blame] | 62 | @Autowired |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 63 | private AccessTokenDao tokenDao; |
| 64 | @Autowired |
| 65 | private OAuth2ClientDao clientDao; |
| 66 | @Autowired |
| 67 | private RandomCodeGenerator codeGenerator; |
| 68 | @Autowired |
| margaretha | 93e602e | 2019-08-07 15:19:56 +0200 | [diff] [blame] | 69 | protected RefreshTokenDao refreshTokenDao; |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 70 | |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 71 | protected String publicClientId = "8bIDtZnH6NvRkW2Fq"; |
| margaretha | ffb8950 | 2022-04-20 12:03:16 +0200 | [diff] [blame] | 72 | // without registered redirect URI |
| 73 | protected String publicClientId2 = "nW5qM63Rb2a7KdT9L"; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 74 | protected String confidentialClientId = "9aHsGW6QflV13ixNpez"; |
| margaretha | 3507469 | 2021-03-26 18:11:59 +0100 | [diff] [blame] | 75 | protected String confidentialClientId2 = "52atrL0ajex_3_5imd9Mgw"; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 76 | protected String superClientId = "fCBbQkAyYzI4NzUxMg"; |
| 77 | protected String clientSecret = "secret"; |
| margaretha | d67b427 | 2022-04-11 17:34:19 +0200 | [diff] [blame] | 78 | protected String state = "thisIsMyState"; |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 79 | |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 80 | public static String ACCESS_TOKEN_TYPE = "access_token"; |
| 81 | public static String REFRESH_TOKEN_TYPE = "refresh_token"; |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 82 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 83 | protected int defaultRefreshTokenExpiry = TimeUtils |
| 84 | .convertTimeToSeconds("365D"); |
| 85 | |
| margaretha | d67b427 | 2022-04-11 17:34:19 +0200 | [diff] [blame] | 86 | protected String clientURL = "http://example.client.com"; |
| 87 | protected String clientRedirectUri = "https://example.client.com/redirect"; |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 88 | |
| margaretha | ffb8950 | 2022-04-20 12:03:16 +0200 | [diff] [blame] | 89 | protected MultivaluedMap<String, String> getQueryParamsFromURI (URI uri) { |
| 90 | return UriComponent.decodeQuery(uri, true); |
| 91 | }; |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 92 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 93 | protected Form getSuperClientForm () { |
| 94 | Form form = new Form(); |
| 95 | form.param("super_client_id", superClientId); |
| 96 | form.param("super_client_secret", clientSecret); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 97 | return form; |
| 98 | } |
| 99 | |
| margaretha | 3cd2d5f | 2023-05-02 14:51:11 +0200 | [diff] [blame] | 100 | protected String parseAuthorizationCode (Response response) { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 101 | |
| margaretha | 3cd2d5f | 2023-05-02 14:51:11 +0200 | [diff] [blame] | 102 | assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(), |
| 103 | response.getStatus()); |
| 104 | |
| 105 | URI redirectUri = response.getLocation(); |
| 106 | MultiValueMap<String, String> params = UriComponentsBuilder |
| 107 | .fromUri(redirectUri).build().getQueryParams(); |
| 108 | return params.getFirst("code"); |
| 109 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 110 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 111 | protected Response requestAuthorizationCode (String responseType, |
| margaretha | d67b427 | 2022-04-11 17:34:19 +0200 | [diff] [blame] | 112 | String clientId, String redirectUri, String scope, String state, |
| 113 | String authHeader) throws KustvaktException { |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 114 | |
| margaretha | cc92959 | 2023-01-31 11:07:35 +0100 | [diff] [blame] | 115 | ClientConfig clientConfig = new ClientConfig(); |
| 116 | clientConfig.property(ClientProperties.FOLLOW_REDIRECTS, false); |
| 117 | Client client = ClientBuilder.newClient(clientConfig); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 118 | |
| margaretha | cc92959 | 2023-01-31 11:07:35 +0100 | [diff] [blame] | 119 | WebTarget request = client.target(getBaseUri()).path(API_VERSION) |
| 120 | .path("oauth2").path("authorize"); |
| 121 | |
| margaretha | 0034a0c | 2022-05-17 10:37:41 +0200 | [diff] [blame] | 122 | if (!responseType.isEmpty()) { |
| 123 | request = request.queryParam("response_type", responseType); |
| 124 | } |
| 125 | if (!clientId.isEmpty()) { |
| 126 | request = request.queryParam("client_id", clientId); |
| 127 | } |
| 128 | if (!redirectUri.isEmpty()) { |
| 129 | request = request.queryParam("redirect_uri", redirectUri); |
| 130 | } |
| 131 | if (!scope.isEmpty()) { |
| 132 | request = request.queryParam("scope", scope); |
| 133 | } |
| 134 | if (!state.isEmpty()) { |
| 135 | request = request.queryParam("state", state); |
| 136 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 137 | |
| 138 | Builder builder = request.request().header(Attributes.AUTHORIZATION, |
| 139 | authHeader); |
| 140 | |
| margaretha | 5f5d3ed | 2023-08-30 23:48:52 +0200 | [diff] [blame] | 141 | return builder.get(); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 142 | } |
| 143 | |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 144 | protected String requestAuthorizationCode (String clientId, |
| margaretha | d67b427 | 2022-04-11 17:34:19 +0200 | [diff] [blame] | 145 | String authHeader) throws KustvaktException { |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 146 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 147 | Response response = requestAuthorizationCode("code", clientId, "", |
| margaretha | 64ea645 | 2023-01-30 12:39:19 +0100 | [diff] [blame] | 148 | "search match_info", "", authHeader); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 149 | assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(), |
| 150 | response.getStatus()); |
| 151 | URI redirectUri = response.getLocation(); |
| 152 | |
| 153 | MultiValueMap<String, String> params = UriComponentsBuilder |
| 154 | .fromUri(redirectUri).build().getQueryParams(); |
| 155 | return params.getFirst("code"); |
| 156 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 157 | |
| 158 | protected String requestAuthorizationCode (String clientId, |
| 159 | String redirect_uri, String authHeader) throws KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 160 | Response response = requestAuthorizationCode("code", clientId, |
| margaretha | 64ea645 | 2023-01-30 12:39:19 +0100 | [diff] [blame] | 161 | redirect_uri, "search", "", authHeader); |
| Akron | dc6d73d | 2020-04-15 16:40:04 +0200 | [diff] [blame] | 162 | assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(), |
| 163 | response.getStatus()); |
| 164 | URI redirectUri = response.getLocation(); |
| 165 | |
| 166 | MultiValueMap<String, String> params = UriComponentsBuilder |
| 167 | .fromUri(redirectUri).build().getQueryParams(); |
| 168 | return params.getFirst("code"); |
| 169 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 170 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 171 | protected Response requestToken (Form form) throws KustvaktException { |
| 172 | return target().path(API_VERSION).path("oauth2").path("token").request() |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 173 | .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32") |
| 174 | .header(HttpHeaders.CONTENT_TYPE, |
| 175 | ContentType.APPLICATION_FORM_URLENCODED) |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 176 | .post(Entity.form(form)); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | // client credentials as form params |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 180 | protected Response requestTokenWithAuthorizationCodeAndForm ( |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 181 | String clientId, String clientSecret, String code) |
| 182 | throws KustvaktException { |
| 183 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 184 | Form form = new Form(); |
| 185 | form.param("grant_type", "authorization_code"); |
| 186 | form.param("client_id", clientId); |
| 187 | form.param("client_secret", clientSecret); |
| 188 | form.param("code", code); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 189 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 190 | return target().path(API_VERSION).path("oauth2").path("token").request() |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 191 | .header(HttpHeaders.CONTENT_TYPE, |
| 192 | ContentType.APPLICATION_FORM_URLENCODED) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 193 | .post(Entity.form(form)); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 194 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 195 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 196 | protected Response requestTokenWithAuthorizationCodeAndForm ( |
| Akron | dc6d73d | 2020-04-15 16:40:04 +0200 | [diff] [blame] | 197 | String clientId, String clientSecret, String code, |
| 198 | String redirectUri) throws KustvaktException { |
| 199 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 200 | Form form = new Form(); |
| 201 | form.param("grant_type", "authorization_code"); |
| 202 | form.param("client_id", clientId); |
| 203 | form.param("client_secret", clientSecret); |
| 204 | form.param("code", code); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 205 | if (redirectUri != null) { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 206 | form.param("redirect_uri", redirectUri); |
| Akron | dc6d73d | 2020-04-15 16:40:04 +0200 | [diff] [blame] | 207 | } |
| 208 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 209 | return target().path(API_VERSION).path("oauth2").path("token").request() |
| Akron | dc6d73d | 2020-04-15 16:40:04 +0200 | [diff] [blame] | 210 | .header(HttpHeaders.CONTENT_TYPE, |
| 211 | ContentType.APPLICATION_FORM_URLENCODED) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 212 | .post(Entity.form(form)); |
| Akron | dc6d73d | 2020-04-15 16:40:04 +0200 | [diff] [blame] | 213 | } |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 214 | |
| 215 | // client credentials in authorization header |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 216 | protected JsonNode requestTokenWithAuthorizationCodeAndHeader ( |
| 217 | String clientId, String code, String authHeader) |
| 218 | throws KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 219 | Form form = new Form(); |
| 220 | form.param("grant_type", "authorization_code"); |
| 221 | form.param("client_id", clientId); |
| 222 | form.param("code", code); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 223 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 224 | Response response = target().path(API_VERSION).path("oauth2") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 225 | .path("token").request() |
| abcpro1 | 241bc4f | 2022-11-07 20:13:57 +0000 | [diff] [blame] | 226 | .header(Attributes.AUTHORIZATION, authHeader) |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 227 | .header(HttpHeaders.CONTENT_TYPE, |
| 228 | ContentType.APPLICATION_FORM_URLENCODED) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 229 | .post(Entity.form(form)); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 230 | |
| margaretha | 3cd2d5f | 2023-05-02 14:51:11 +0200 | [diff] [blame] | 231 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 232 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 233 | String entity = response.readEntity(String.class); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 234 | return JsonUtils.readTree(entity); |
| 235 | } |
| 236 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 237 | protected Response requestTokenWithDoryPassword (String clientId, |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 238 | String clientSecret) throws KustvaktException { |
| margaretha | 230effb | 2018-11-29 17:28:18 +0100 | [diff] [blame] | 239 | return requestTokenWithPassword(clientId, clientSecret, "dory", |
| 240 | "password"); |
| 241 | } |
| 242 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 243 | protected Response requestTokenWithPassword (String clientId, |
| margaretha | 230effb | 2018-11-29 17:28:18 +0100 | [diff] [blame] | 244 | String clientSecret, String username, String password) |
| 245 | throws KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 246 | Form form = new Form(); |
| 247 | form.param("grant_type", "password"); |
| 248 | form.param("client_id", clientId); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 249 | if (clientSecret != null && !clientSecret.isEmpty()) { |
| margaretha | 7ac20b1 | 2023-09-27 09:40:16 +0200 | [diff] [blame] | 250 | form.param("client_secret", clientSecret); |
| 251 | } |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 252 | form.param("username", username); |
| 253 | form.param("password", password); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 254 | |
| 255 | return requestToken(form); |
| 256 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 257 | |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 258 | protected void testRequestTokenWithRevokedRefreshToken (String clientId, |
| 259 | String clientSecret, String refreshToken) throws KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 260 | Form form = new Form(); |
| 261 | form.param("grant_type", GrantType.REFRESH_TOKEN.toString()); |
| 262 | form.param("client_id", clientId); |
| 263 | form.param("client_secret", clientSecret); |
| 264 | form.param("refresh_token", refreshToken); |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 265 | if (clientSecret != null) { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 266 | form.param("client_secret", clientSecret); |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 267 | } |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 268 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 269 | Response response = target().path(API_VERSION).path("oauth2") |
| 270 | .path("token").request() |
| 271 | .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32") |
| 272 | .header(HttpHeaders.CONTENT_TYPE, |
| 273 | ContentType.APPLICATION_FORM_URLENCODED) |
| 274 | .post(Entity.form(form)); |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 275 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 276 | String entity = response.readEntity(String.class); |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 277 | JsonNode node = JsonUtils.readTree(entity); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 278 | assertEquals(OAuth2Error.INVALID_GRANT.getCode(), |
| 279 | node.at("/error").asText()); |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 280 | assertEquals("Refresh token has been revoked", |
| 281 | node.at("/error_description").asText()); |
| 282 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 283 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 284 | protected Response registerClient (String username, OAuth2ClientJson json) |
| 285 | throws ProcessingException, KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 286 | return target().path(API_VERSION).path("oauth2").path("client") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 287 | .path("register").request() |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 288 | .header(Attributes.AUTHORIZATION, |
| 289 | HttpAuthorizationHandler |
| 290 | .createBasicAuthorizationHeaderValue(username, |
| 291 | "password")) |
| 292 | .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32") |
| 293 | .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 294 | .post(Entity.json(json)); |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 295 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 296 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 297 | protected Response registerConfidentialClient (String username) |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 298 | throws KustvaktException { |
| margaretha | c750cbb | 2018-12-11 12:47:02 +0100 | [diff] [blame] | 299 | |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 300 | OAuth2ClientJson json = new OAuth2ClientJson(); |
| 301 | json.setName("OAuth2ClientTest"); |
| 302 | json.setType(OAuth2ClientType.CONFIDENTIAL); |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 303 | json.setUrl(clientURL); |
| 304 | json.setRedirectURI(clientRedirectUri); |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 305 | json.setDescription("This is a confidential test client."); |
| 306 | |
| 307 | return registerClient(username, json); |
| 308 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 309 | |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 310 | protected void testConfidentialClientInfo (String clientId, String username) |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 311 | throws ProcessingException, KustvaktException { |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 312 | JsonNode clientInfo = retrieveClientInfo(clientId, username); |
| margaretha | 79f0144 | 2022-05-04 12:03:47 +0200 | [diff] [blame] | 313 | assertEquals(clientId, clientInfo.at("/client_id").asText()); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 314 | assertEquals("OAuth2ClientTest", |
| 315 | clientInfo.at("/client_name").asText()); |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 316 | assertEquals(OAuth2ClientType.CONFIDENTIAL.name(), |
| margaretha | 79f0144 | 2022-05-04 12:03:47 +0200 | [diff] [blame] | 317 | clientInfo.at("/client_type").asText()); |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 318 | assertEquals(username, clientInfo.at("/registered_by").asText()); |
| margaretha | 79f0144 | 2022-05-04 12:03:47 +0200 | [diff] [blame] | 319 | assertEquals(clientURL, clientInfo.at("/client_url").asText()); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 320 | assertEquals(clientRedirectUri, |
| margaretha | 79f0144 | 2022-05-04 12:03:47 +0200 | [diff] [blame] | 321 | clientInfo.at("/client_redirect_uri").asText()); |
| margaretha | 977fabe | 2022-04-28 09:23:47 +0200 | [diff] [blame] | 322 | // 31536000 seconds |
| margaretha | 79f0144 | 2022-05-04 12:03:47 +0200 | [diff] [blame] | 323 | assertEquals(defaultRefreshTokenExpiry, |
| margaretha | 977fabe | 2022-04-28 09:23:47 +0200 | [diff] [blame] | 324 | clientInfo.at("/refresh_token_expiry").asInt()); |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 325 | assertNotNull(clientInfo.at("/description")); |
| margaretha | d716312 | 2022-04-11 09:42:41 +0200 | [diff] [blame] | 326 | assertNotNull(clientInfo.at("/registration_date")); |
| 327 | assertTrue(clientInfo.at("/permitted").asBoolean()); |
| 328 | assertTrue(clientInfo.at("/source").isMissingNode()); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 329 | |
| margaretha | 3ef1b81 | 2022-04-06 11:32:54 +0200 | [diff] [blame] | 330 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 331 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 332 | protected void deregisterClient (String username, String clientId) |
| 333 | throws ProcessingException, KustvaktException { |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 334 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 335 | Response response = target().path(API_VERSION).path("oauth2") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 336 | .path("client").path("deregister").path(clientId).request() |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 337 | .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler |
| 338 | .createBasicAuthorizationHeaderValue(username, "pass")) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 339 | .delete(); |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 340 | |
| 341 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| 342 | } |
| 343 | |
| 344 | protected JsonNode retrieveClientInfo (String clientId, String username) |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 345 | throws ProcessingException, KustvaktException { |
| margaretha | b22a585 | 2023-01-27 14:43:36 +0100 | [diff] [blame] | 346 | Form form = new Form(); |
| 347 | form.param("super_client_id", superClientId); |
| 348 | form.param("super_client_secret", clientSecret); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 349 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 350 | Response response = target().path(API_VERSION).path("oauth2") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 351 | .path("client").path(clientId).request() |
| margaretha | 60b65d4 | 2024-06-06 09:05:16 +0200 | [diff] [blame] | 352 | .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler |
| 353 | .createBasicAuthorizationHeaderValue(username, "pass")) |
| margaretha | b22a585 | 2023-01-27 14:43:36 +0100 | [diff] [blame] | 354 | .header(HttpHeaders.CONTENT_TYPE, |
| 355 | ContentType.APPLICATION_FORM_URLENCODED) |
| 356 | .post(Entity.form(form)); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 357 | |
| 358 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 359 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 360 | String entity = response.readEntity(String.class); |
| margaretha | e28cdd9 | 2022-03-29 09:42:08 +0200 | [diff] [blame] | 361 | return JsonUtils.readTree(entity); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 362 | } |
| margaretha | 230effb | 2018-11-29 17:28:18 +0100 | [diff] [blame] | 363 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 364 | protected Response searchWithAccessToken (String accessToken) { |
| 365 | return target().path(API_VERSION).path("search") |
| margaretha | 230effb | 2018-11-29 17:28:18 +0100 | [diff] [blame] | 366 | .queryParam("q", "Wasser").queryParam("ql", "poliqarp") |
| abcpro1 | 241bc4f | 2022-11-07 20:13:57 +0000 | [diff] [blame] | 367 | .request() |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 368 | .header(Attributes.AUTHORIZATION, "Bearer " + accessToken) |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 369 | .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").get(); |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 370 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 371 | |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 372 | protected void testSearchWithOAuth2Token (String accessToken) |
| 373 | throws KustvaktException, IOException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 374 | Response response = searchWithAccessToken(accessToken); |
| 375 | String entity = response.readEntity(String.class); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 376 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 377 | JsonNode node = JsonUtils.readTree(entity); |
| 378 | assertNotNull(node); |
| 379 | assertEquals(25, node.at("/matches").size()); |
| 380 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 381 | |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 382 | protected void testSearchWithRevokedAccessToken (String accessToken) |
| 383 | throws KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 384 | Response response = searchWithAccessToken(accessToken); |
| 385 | String entity = response.readEntity(String.class); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 386 | assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); |
| margaretha | d484156 | 2022-06-01 12:24:47 +0200 | [diff] [blame] | 387 | |
| 388 | JsonNode node = JsonUtils.readTree(entity); |
| 389 | assertEquals(StatusCodes.INVALID_ACCESS_TOKEN, |
| 390 | node.at("/errors/0/0").asInt()); |
| 391 | assertEquals("Access token is invalid", |
| 392 | node.at("/errors/0/1").asText()); |
| 393 | } |
| 394 | |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 395 | protected void testRevokeTokenViaSuperClient (String token, |
| 396 | String userAuthHeader) { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 397 | Form form = new Form(); |
| 398 | form.param("token", token); |
| 399 | form.param("super_client_id", superClientId); |
| 400 | form.param("super_client_secret", clientSecret); |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 401 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 402 | Response response = target().path(API_VERSION).path("oauth2") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 403 | .path("revoke").path("super").request() |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 404 | .header(HttpHeaders.CONTENT_TYPE, |
| 405 | ContentType.APPLICATION_FORM_URLENCODED) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 406 | .header(Attributes.AUTHORIZATION, userAuthHeader) |
| 407 | .post(Entity.form(form)); |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 408 | |
| 409 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 410 | assertEquals("SUCCESS", response.readEntity(String.class)); |
| margaretha | 0afd44a | 2020-02-05 10:49:21 +0100 | [diff] [blame] | 411 | } |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 412 | |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 413 | protected void testRevokeToken (String token, String clientId, |
| 414 | String clientSecret, String tokenType) { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 415 | Form form = new Form(); |
| 416 | form.param("token_type", tokenType); |
| 417 | form.param("token", token); |
| 418 | form.param("client_id", clientId); |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 419 | if (clientSecret != null) { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 420 | form.param("client_secret", clientSecret); |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 421 | } |
| 422 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 423 | Response response = target().path(API_VERSION).path("oauth2") |
| 424 | .path("revoke").request() |
| 425 | .header(HttpHeaders.CONTENT_TYPE, |
| 426 | ContentType.APPLICATION_FORM_URLENCODED) |
| 427 | .post(Entity.form(form)); |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 428 | |
| 429 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 430 | assertEquals("SUCCESS", response.readEntity(String.class)); |
| margaretha | 74110b7 | 2022-03-28 12:16:51 +0200 | [diff] [blame] | 431 | } |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 432 | |
| margaretha | 1ef2a03 | 2024-06-11 11:39:57 +0200 | [diff] [blame] | 433 | protected JsonNode listUserClients (String username) |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 434 | throws ProcessingException, KustvaktException { |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 435 | Form form = getSuperClientForm(); |
| 436 | Response response = target().path(API_VERSION).path("oauth2") |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 437 | .path("client").path("list").request() |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 438 | .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler |
| 439 | .createBasicAuthorizationHeaderValue(username, "pwd")) |
| 440 | .header(HttpHeaders.CONTENT_TYPE, |
| 441 | ContentType.APPLICATION_FORM_URLENCODED) |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 442 | .post(Entity.form(form)); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 443 | |
| 444 | assertEquals(Status.OK.getStatusCode(), response.getStatus()); |
| 445 | |
| abcpro1 | 73fe8f2 | 2022-11-08 19:56:52 +0000 | [diff] [blame] | 446 | String entity = response.readEntity(String.class); |
| margaretha | e20a280 | 2022-04-21 12:37:38 +0200 | [diff] [blame] | 447 | return JsonUtils.readTree(entity); |
| 448 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 449 | |
| margaretha | 45ba733 | 2023-01-31 11:39:52 +0100 | [diff] [blame] | 450 | protected void testInvalidRedirectUri (String entity, String contentType, |
| 451 | boolean includeState, int status) throws KustvaktException { |
| margaretha | 9436ebe | 2022-04-22 11:48:37 +0200 | [diff] [blame] | 452 | JsonNode node = JsonUtils.readTree(entity); |
| margaretha | 5f5d3ed | 2023-08-30 23:48:52 +0200 | [diff] [blame] | 453 | assertEquals(OAuth2Error.INVALID_REQUEST.getCode(), |
| margaretha | 9436ebe | 2022-04-22 11:48:37 +0200 | [diff] [blame] | 454 | node.at("/error").asText()); |
| 455 | assertEquals("Invalid redirect URI", |
| 456 | node.at("/error_description").asText()); |
| 457 | if (includeState) { |
| 458 | assertEquals(state, node.at("/state").asText()); |
| 459 | } |
| 460 | |
| margaretha | 45ba733 | 2023-01-31 11:39:52 +0100 | [diff] [blame] | 461 | assertEquals("application/json;charset=utf-8", contentType); |
| margaretha | 9436ebe | 2022-04-22 11:48:37 +0200 | [diff] [blame] | 462 | assertEquals(Status.BAD_REQUEST.getStatusCode(), status); |
| 463 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 464 | |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 465 | protected String createExpiredAccessToken () throws KustvaktException { |
| 466 | String authToken = codeGenerator.createRandomCode(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 467 | |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 468 | // create new access token |
| 469 | OAuth2Client client = clientDao.retrieveClientById(publicClientId); |
| 470 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 471 | ZonedDateTime now = ZonedDateTime |
| 472 | .now(ZoneId.of(Attributes.DEFAULT_TIME_ZONE)); |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 473 | Set<AccessScope> scopes = new HashSet<>(); |
| 474 | scopes.add(new AccessScope(OAuth2Scope.EDIT_VC)); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 475 | |
| margaretha | ca5472a | 2023-09-22 18:00:03 +0200 | [diff] [blame] | 476 | AccessToken accessToken = new AccessToken(); |
| 477 | accessToken.setCreatedDate(now.minusSeconds(5)); |
| 478 | accessToken.setExpiryDate(now.minusSeconds(3)); |
| 479 | accessToken.setToken(authToken); |
| 480 | accessToken.setScopes(scopes); |
| 481 | accessToken.setUserId("marlin"); |
| 482 | accessToken.setClient(client); |
| 483 | accessToken.setUserAuthenticationTime(now.minusSeconds(5)); |
| 484 | tokenDao.storeAccessToken(accessToken); |
| 485 | return authToken; |
| 486 | } |
| margaretha | f008512 | 2018-08-16 16:19:53 +0200 | [diff] [blame] | 487 | } |