blob: 8ab3e2aa9493e2fff49e74362adf9af1adfcedb3 [file] [log] [blame]
margaretha0e8f4e72018-04-05 14:11:52 +02001package de.ids_mannheim.korap.web.controller;
2
margaretha5f5d3ed2023-08-30 23:48:52 +02003import java.net.URI;
4import java.net.URISyntaxException;
margarethaa2ce63d2018-06-28 10:11:43 +02005import java.time.ZonedDateTime;
margaretha4993eb72023-09-27 10:54:34 +02006import java.util.List;
margarethaa2ce63d2018-06-28 10:11:43 +02007
margaretha0e8f4e72018-04-05 14:11:52 +02008import org.springframework.beans.factory.annotation.Autowired;
9import org.springframework.stereotype.Controller;
10
margarethab8a9d4e2023-10-25 12:00:10 +020011import com.nimbusds.oauth2.sdk.AccessTokenResponse;
margaretha5f5d3ed2023-08-30 23:48:52 +020012import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse;
margaretha7ac20b12023-09-27 09:40:16 +020013import com.nimbusds.oauth2.sdk.AuthorizationGrant;
14import com.nimbusds.oauth2.sdk.ClientCredentialsGrant;
margaretha5f5d3ed2023-08-30 23:48:52 +020015import com.nimbusds.oauth2.sdk.OAuth2Error;
margaretha7ac20b12023-09-27 09:40:16 +020016import com.nimbusds.oauth2.sdk.ParseException;
17import com.nimbusds.oauth2.sdk.Scope;
18import com.nimbusds.oauth2.sdk.TokenRequest;
19import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
20import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
21import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
22import com.nimbusds.oauth2.sdk.auth.ClientSecretPost;
23import com.nimbusds.oauth2.sdk.id.ClientID;
margaretha5f5d3ed2023-08-30 23:48:52 +020024
margaretha2df06602018-11-14 19:10:30 +010025import de.ids_mannheim.korap.constant.OAuth2Scope;
margaretha0e8f4e72018-04-05 14:11:52 +020026import de.ids_mannheim.korap.exceptions.KustvaktException;
margaretha35074692021-03-26 18:11:59 +010027import de.ids_mannheim.korap.exceptions.StatusCodes;
margaretha4993eb72023-09-27 10:54:34 +020028import de.ids_mannheim.korap.oauth2.dto.OAuth2TokenDto;
margaretha5f5d3ed2023-08-30 23:48:52 +020029import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
margaretha835178d2018-08-15 19:04:03 +020030import de.ids_mannheim.korap.oauth2.service.OAuth2ScopeService;
margaretha7ac20b12023-09-27 09:40:16 +020031import de.ids_mannheim.korap.oauth2.service.OAuth2TokenService;
margaretha07402f42018-05-07 19:07:45 +020032import de.ids_mannheim.korap.security.context.TokenContext;
margaretha4993eb72023-09-27 10:54:34 +020033import de.ids_mannheim.korap.utils.ParameterChecker;
margarethaf839dde2018-04-16 17:52:57 +020034import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
margaretha398f4722019-01-09 19:07:20 +010035import de.ids_mannheim.korap.web.filter.APIVersionFilter;
margaretha07402f42018-05-07 19:07:45 +020036import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
margarethadb5da372023-09-01 11:02:52 +020037import de.ids_mannheim.korap.web.filter.BlockingFilter;
margaretha96c309d2023-08-16 12:24:12 +020038import de.ids_mannheim.korap.web.utils.ResourceFilters;
margaretha5f5d3ed2023-08-30 23:48:52 +020039import jakarta.servlet.http.HttpServletRequest;
margaretha93bfbea2023-11-06 21:09:21 +010040import jakarta.validation.constraints.NotEmpty;
margaretha751608c2023-09-26 08:48:30 +020041import jakarta.ws.rs.Consumes;
42import jakarta.ws.rs.FormParam;
margaretha96c309d2023-08-16 12:24:12 +020043import jakarta.ws.rs.GET;
margaretha751608c2023-09-26 08:48:30 +020044import jakarta.ws.rs.POST;
margaretha96c309d2023-08-16 12:24:12 +020045import jakarta.ws.rs.Path;
46import jakarta.ws.rs.Produces;
47import jakarta.ws.rs.QueryParam;
48import jakarta.ws.rs.core.Context;
49import jakarta.ws.rs.core.MediaType;
margaretha751608c2023-09-26 08:48:30 +020050import jakarta.ws.rs.core.MultivaluedMap;
margaretha96c309d2023-08-16 12:24:12 +020051import jakarta.ws.rs.core.Response;
52import jakarta.ws.rs.core.SecurityContext;
margaretha751608c2023-09-26 08:48:30 +020053import jakarta.ws.rs.core.UriBuilder;
margaretha0e8f4e72018-04-05 14:11:52 +020054
margaretha398f4722019-01-09 19:07:20 +010055/**
56 * OAuth2Controller describes OAuth2 web API for authorization
57 * for both internal (e.g Kalamar) and external (third party) clients.
58 *
59 * Possible authorization scopes are listed in {@link OAuth2Scope} For
60 * more information about OAuth2 authorization mechanisms, see RFC
61 * 6749.
62 *
63 * @author margaretha
64 *
65 */
margaretha0e8f4e72018-04-05 14:11:52 +020066@Controller
margarethaee0cbfe2018-08-28 17:47:14 +020067@Path("{version}/oauth2")
margarethadb5da372023-09-01 11:02:52 +020068@ResourceFilters({ APIVersionFilter.class, AuthenticationFilter.class,
69 BlockingFilter.class })
margaretha45ba7332023-01-31 11:39:52 +010070@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
margaretha0e8f4e72018-04-05 14:11:52 +020071public class OAuth2Controller {
72
73 @Autowired
margarethaf839dde2018-04-16 17:52:57 +020074 private OAuth2ResponseHandler responseHandler;
margarethadb5da372023-09-01 11:02:52 +020075
margaretha7ac20b12023-09-27 09:40:16 +020076 @Autowired
77 private OAuth2TokenService tokenService;
margaretha0e8f4e72018-04-05 14:11:52 +020078 @Autowired
margaretha5f5d3ed2023-08-30 23:48:52 +020079 private OAuth2AuthorizationService authorizationService;
margaretha35e1ca22023-11-16 22:00:01 +010080
margaretha835178d2018-08-15 19:04:03 +020081 @Autowired
82 private OAuth2ScopeService scopeService;
margarethafb027f92018-04-23 20:00:13 +020083
margarethaa452c5e2018-04-25 22:48:09 +020084 /**
85 * Requests an authorization code.
margarethafb027f92018-04-23 20:00:13 +020086 *
margarethaa452c5e2018-04-25 22:48:09 +020087 * Kustvakt supports authorization only with Kalamar as the
88 * authorization web-frontend or user interface. Thus
margaretha07402f42018-05-07 19:07:45 +020089 * authorization code request requires user authentication
margarethac750cbb2018-12-11 12:47:02 +010090 * using authorization header.
margarethaa452c5e2018-04-25 22:48:09 +020091 *
92 * <br /><br />
93 * RFC 6749:
94 * If the client omits the scope parameter when requesting
95 * authorization, the authorization server MUST either process the
96 * request using a pre-defined default value or fail the request
97 * indicating an invalid scope.
98 *
margaretha07402f42018-05-07 19:07:45 +020099 * @param request
100 * HttpServletRequest
101 * @param form
102 * form parameters
margarethaa452c5e2018-04-25 22:48:09 +0200103 * @return a redirect URL
margarethafb027f92018-04-23 20:00:13 +0200104 */
margaretha751608c2023-09-26 08:48:30 +0200105 @Deprecated
106 @POST
107 @Path("authorize")
108 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
109 public Response requestAuthorizationCode (
110 @Context HttpServletRequest request,
margaretha35e1ca22023-11-16 22:00:01 +0100111 @Context SecurityContext context, @FormParam("scope") String scope,
margaretha751608c2023-09-26 08:48:30 +0200112 @FormParam("state") String state,
113 @FormParam("client_id") String clientId,
114 @FormParam("redirect_uri") String redirectUri,
115 MultivaluedMap<String, String> form) {
116
117 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
118 String username = tokenContext.getUsername();
119 ZonedDateTime authTime = tokenContext.getAuthenticationTime();
120
121 URI requestURI;
122 UriBuilder builder = UriBuilder.fromPath(request.getRequestURI());
123 for (String key : form.keySet()) {
124 builder.queryParam(key, form.get(key).toArray());
125 }
126 requestURI = builder.build();
margaretha35e1ca22023-11-16 22:00:01 +0100127
margaretha751608c2023-09-26 08:48:30 +0200128 try {
129 scopeService.verifyScope(tokenContext, OAuth2Scope.AUTHORIZE);
margaretha35e1ca22023-11-16 22:00:01 +0100130 URI uri = authorizationService.requestAuthorizationCode(requestURI,
131 clientId, redirectUri, scope, state, username, authTime);
margaretha751608c2023-09-26 08:48:30 +0200132 return responseHandler.sendRedirect(uri);
133 }
134 catch (KustvaktException e) {
135 e = authorizationService.checkRedirectUri(e, clientId, redirectUri);
136 if (e.getRedirectUri() != null) {
margaretha35e1ca22023-11-16 22:00:01 +0100137 AuthorizationErrorResponse errorResponse = authorizationService
138 .createAuthorizationError(e, state);
margaretha751608c2023-09-26 08:48:30 +0200139 return responseHandler.sendRedirect(errorResponse.toURI());
140 }
141 else {
142 throw responseHandler.throwit(e, state);
margaretha35e1ca22023-11-16 22:00:01 +0100143 }
margaretha751608c2023-09-26 08:48:30 +0200144 }
145 }
margaretha35e1ca22023-11-16 22:00:01 +0100146
margarethad67b4272022-04-11 17:34:19 +0200147 @GET
148 @Path("authorize")
149 public Response requestAuthorizationCode (
150 @Context HttpServletRequest request,
151 @Context SecurityContext context,
margaretha5f5d3ed2023-08-30 23:48:52 +0200152 @QueryParam("response_type") String responseType,
margarethaffb89502022-04-20 12:03:16 +0200153 @QueryParam("client_id") String clientId,
154 @QueryParam("redirect_uri") String redirectUri,
margaretha5f5d3ed2023-08-30 23:48:52 +0200155 @QueryParam("scope") String scope,
156 @QueryParam("state") String state) {
margarethad67b4272022-04-11 17:34:19 +0200157
158 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
159 String username = tokenContext.getUsername();
160 ZonedDateTime authTime = tokenContext.getAuthenticationTime();
161
margaretha5f5d3ed2023-08-30 23:48:52 +0200162 URI requestURI;
163 try {
margaretha35e1ca22023-11-16 22:00:01 +0100164 requestURI = new URI(
165 request.getRequestURI() + "?" + request.getQueryString());
margaretha5f5d3ed2023-08-30 23:48:52 +0200166 }
167 catch (URISyntaxException e) {
168 KustvaktException ke = new KustvaktException(
169 StatusCodes.INVALID_REQUEST, "Failed parsing request URI.",
170 OAuth2Error.INVALID_REQUEST_URI);
171 throw responseHandler.throwit(ke, state);
172 }
margaretha35e1ca22023-11-16 22:00:01 +0100173
margarethad67b4272022-04-11 17:34:19 +0200174 try {
175 scopeService.verifyScope(tokenContext, OAuth2Scope.AUTHORIZE);
margaretha35e1ca22023-11-16 22:00:01 +0100176 URI uri = authorizationService.requestAuthorizationCode(requestURI,
177 clientId, redirectUri, scope, state, username, authTime);
margarethad67b4272022-04-11 17:34:19 +0200178 return responseHandler.sendRedirect(uri);
179 }
margarethad67b4272022-04-11 17:34:19 +0200180 catch (KustvaktException e) {
margarethaffb89502022-04-20 12:03:16 +0200181 e = authorizationService.checkRedirectUri(e, clientId, redirectUri);
margaretha5f5d3ed2023-08-30 23:48:52 +0200182 if (e.getRedirectUri() != null) {
margaretha35e1ca22023-11-16 22:00:01 +0100183 AuthorizationErrorResponse errorResponse = authorizationService
184 .createAuthorizationError(e, state);
margaretha5f5d3ed2023-08-30 23:48:52 +0200185 return responseHandler.sendRedirect(errorResponse.toURI());
186 }
187 else {
188 throw responseHandler.throwit(e, state);
margaretha35e1ca22023-11-16 22:00:01 +0100189 }
margarethad67b4272022-04-11 17:34:19 +0200190 }
191 }
margarethafb027f92018-04-23 20:00:13 +0200192
margarethaa452c5e2018-04-25 22:48:09 +0200193 /**
194 * Grants a client an access token, namely a string used in
195 * authenticated requests representing user authorization for
margarethadc515072018-08-03 17:01:19 +0200196 * the client to access user resources. An additional refresh
margaretha35074692021-03-26 18:11:59 +0100197 * token strictly associated to the access token is also granted
198 * for confidential clients. Both public and confidential clients
199 * may issue multiple access tokens.
margarethaa0486272018-04-12 19:59:31 +0200200 *
margarethaa452c5e2018-04-25 22:48:09 +0200201 * <br /><br />
202 *
margaretha35074692021-03-26 18:11:59 +0100203 * Confidential clients may request refresh access token using
204 * this endpoint. This request will grant a new access token.
205 *
206 * Usually the given refresh token is not changed and can be used
207 * until it expires. However, currently there is a limitation of
208 * one access token per one refresh token. Thus, the given refresh
209 * token will be revoked, and a new access token and a new refresh
210 * token will be returned.
margarethadc515072018-08-03 17:01:19 +0200211 *
212 * <br /><br />
213 *
214 * Client credentials for authentication can be provided either as
215 * an authorization header with Basic authentication scheme or as
216 * form parameters in the request body.
217 *
218 * <br /><br />
219 *
220 * OAuth2 specification describes various ways of requesting an
221 * access token. Kustvakt supports:
margarethaa452c5e2018-04-25 22:48:09 +0200222 * <ul>
223 * <li> Authorization code grant: obtains authorization from a
224 * third party application. Required parameters: grant_type,
225 * code, client_id, redirect_uri (if specified in the
226 * authorization request), client_secret (if the client is
227 * confidential or issued a secret).
228 * </li>
229 * <li> Resource owner password grant: strictly for clients that
230 * are parts of KorAP. Clients use user credentials, e.g. Kalamar
231 * (front-end) with login form. Required parameters: grant_type,
232 * username, password, client_id, client_secret (if the client is
233 * confidential or issued a secret). Optional parameters: scope.
234 * </li>
235 * <li> Client credentials grant: strictly for clients that are
236 * parts of KorAP. Clients access their own resources, not on
237 * behalf of a user. Required parameters: grant_type, client_id,
238 * client_secret. Optional parameters: scope.
239 * </li>
240 * </ul>
241 *
margarethaa452c5e2018-04-25 22:48:09 +0200242 * RFC 6749: The value of the scope parameter is expressed as a
243 * list of space-delimited, case-sensitive strings defined by the
244 * authorization server.
245 *
246 * @param request
247 * the request
margarethaa452c5e2018-04-25 22:48:09 +0200248 * @param form
249 * form parameters in a map
250 * @return a JSON object containing an access token, a refresh
251 * token, a token type and the token expiration in seconds
252 * if successful, an error code and an error description
253 * otherwise.
margarethaa0486272018-04-12 19:59:31 +0200254 */
margaretha7ac20b12023-09-27 09:40:16 +0200255 @POST
256 @Path("token")
margaretha35e1ca22023-11-16 22:00:01 +0100257 @ResourceFilters({ APIVersionFilter.class })
margaretha7ac20b12023-09-27 09:40:16 +0200258 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
259 public Response requestAccessToken (@Context HttpServletRequest request,
margaretha93bfbea2023-11-06 21:09:21 +0100260 @NotEmpty @FormParam("grant_type") String grantType,
261 @NotEmpty @FormParam("client_id") String clientId,
margaretha7ac20b12023-09-27 09:40:16 +0200262 @FormParam("client_secret") String clientSecret,
263 MultivaluedMap<String, String> form) {
264
margaretha7ac20b12023-09-27 09:40:16 +0200265 try {
266 URI requestURI;
margaretha35e1ca22023-11-16 22:00:01 +0100267 UriBuilder builder = UriBuilder
268 .fromPath(request.getRequestURL().toString());
margaretha7ac20b12023-09-27 09:40:16 +0200269 for (String key : form.keySet()) {
270 builder.queryParam(key, form.get(key).toArray());
271 }
272 requestURI = builder.build();
margaretha35e1ca22023-11-16 22:00:01 +0100273
margaretha7ac20b12023-09-27 09:40:16 +0200274 try {
margaretha35e1ca22023-11-16 22:00:01 +0100275 AuthorizationGrant authGrant = AuthorizationGrant.parse(form);
276
margaretha7ac20b12023-09-27 09:40:16 +0200277 ClientAuthentication clientAuth = null;
278 String authorizationHeader = request.getHeader("Authorization");
margaretha35e1ca22023-11-16 22:00:01 +0100279 if (authorizationHeader != null
280 && !authorizationHeader.isEmpty()) {
margaretha7ac20b12023-09-27 09:40:16 +0200281 clientAuth = ClientSecretBasic.parse(authorizationHeader);
282 }
283 else if (authGrant instanceof ClientCredentialsGrant) {
284 // this doesn't allow public clients
285 clientAuth = ClientSecretPost.parse(form);
286 }
margaretha35e1ca22023-11-16 22:00:01 +0100287
margaretha7ac20b12023-09-27 09:40:16 +0200288 TokenRequest tokenRequest = null;
margaretha35e1ca22023-11-16 22:00:01 +0100289 if (clientAuth != null) {
margaretha7ac20b12023-09-27 09:40:16 +0200290 ClientAuthenticationMethod method = clientAuth.getMethod();
margaretha35e1ca22023-11-16 22:00:01 +0100291 if (method.equals(
292 ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) {
margaretha7ac20b12023-09-27 09:40:16 +0200293 ClientSecretBasic basic = (ClientSecretBasic) clientAuth;
294 clientSecret = basic.getClientSecret().getValue();
295 clientId = basic.getClientID().getValue();
296 }
margaretha35e1ca22023-11-16 22:00:01 +0100297 else if (method.equals(
298 ClientAuthenticationMethod.CLIENT_SECRET_POST)) {
margaretha7ac20b12023-09-27 09:40:16 +0200299 ClientSecretPost post = (ClientSecretPost) clientAuth;
300 clientSecret = post.getClientSecret().getValue();
301 clientId = post.getClientID().getValue();
302 }
margaretha35e1ca22023-11-16 22:00:01 +0100303
304 tokenRequest = new TokenRequest(requestURI, clientAuth,
margaretha7ac20b12023-09-27 09:40:16 +0200305 AuthorizationGrant.parse(form),
306 Scope.parse(form.getFirst("scope")));
307 }
308 else {
309 // requires ClientAuthentication for client_credentials grant
310 tokenRequest = new TokenRequest(requestURI,
margaretha35e1ca22023-11-16 22:00:01 +0100311 new ClientID(clientId),
312 AuthorizationGrant.parse(form),
313 Scope.parse(form.getFirst("scope")));
margaretha7ac20b12023-09-27 09:40:16 +0200314 }
margaretha35e1ca22023-11-16 22:00:01 +0100315
316 AccessTokenResponse r = tokenService.requestAccessToken(
317 tokenRequest, clientId, clientSecret);
margarethab8a9d4e2023-10-25 12:00:10 +0200318 return responseHandler.createResponse(r);
margaretha7ac20b12023-09-27 09:40:16 +0200319 }
320 catch (ParseException | IllegalArgumentException e) {
321 throw new KustvaktException(StatusCodes.INVALID_REQUEST,
margaretha35e1ca22023-11-16 22:00:01 +0100322 e.getMessage(), OAuth2Error.INVALID_REQUEST);
margaretha7ac20b12023-09-27 09:40:16 +0200323 }
margaretha35e1ca22023-11-16 22:00:01 +0100324
margaretha7ac20b12023-09-27 09:40:16 +0200325 }
326 catch (KustvaktException e) {
327 throw responseHandler.throwit(e);
328 }
margaretha7ac20b12023-09-27 09:40:16 +0200329 }
margarethaec247dd2018-06-12 21:55:46 +0200330
margarethadc515072018-08-03 17:01:19 +0200331 /**
margaretha1ef36bd2018-08-14 18:17:05 +0200332 * Revokes either an access token or a refresh token. Revoking a
333 * refresh token also revokes all access token associated with the
334 * refresh token.
margarethadc515072018-08-03 17:01:19 +0200335 *
336 * RFC 7009
337 * Client authentication for confidential client
338 *
339 * @param request
340 * @param form
margaretha1ef36bd2018-08-14 18:17:05 +0200341 * containing
342 * client_id,
343 * client_secret (required for confidential clients),
344 * token,
345 * token_type (optional)
margarethadc515072018-08-03 17:01:19 +0200346 * @return 200 if token invalidation is successful or the given
347 * token is invalid
348 */
margaretha4993eb72023-09-27 10:54:34 +0200349 @POST
350 @Path("revoke")
margaretha35e1ca22023-11-16 22:00:01 +0100351 @ResourceFilters({ APIVersionFilter.class })
margaretha4993eb72023-09-27 10:54:34 +0200352 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
353 public Response revokeAccessToken (@Context HttpServletRequest request,
354 @FormParam("client_id") String clientId,
355 @FormParam("client_secret") String clientSecret,
356 @FormParam("token") String token,
357 @FormParam("token_type") String tokenType) {
358
359 try {
360 ParameterChecker.checkStringValue("client_id", clientId);
361 ParameterChecker.checkStringValue("token", token);
margaretha35e1ca22023-11-16 22:00:01 +0100362 tokenService.revokeToken(clientId, clientSecret, token, tokenType);
363
margaretha4993eb72023-09-27 10:54:34 +0200364 return Response.ok("SUCCESS").build();
365 }
366 catch (KustvaktException e) {
367 throw responseHandler.throwit(e);
368 }
369 }
370
371 @POST
372 @Path("revoke/super")
373 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
374 public Response revokeTokenViaSuperClient (@Context SecurityContext context,
375 @Context HttpServletRequest request,
376 @FormParam("super_client_id") String superClientId,
377 @FormParam("super_client_secret") String superClientSecret,
378 @FormParam("token") String token) {
379
380 try {
381 ParameterChecker.checkStringValue("super_client_id", superClientId);
382 ParameterChecker.checkStringValue("super_client_secret",
383 superClientSecret);
384 ParameterChecker.checkStringValue("token", token);
margaretha35e1ca22023-11-16 22:00:01 +0100385
386 TokenContext tokenContext = (TokenContext) context
387 .getUserPrincipal();
margaretha4993eb72023-09-27 10:54:34 +0200388 String username = tokenContext.getUsername();
margaretha35e1ca22023-11-16 22:00:01 +0100389
margaretha4993eb72023-09-27 10:54:34 +0200390 tokenService.revokeTokensViaSuperClient(username, superClientId,
391 superClientSecret, token);
392 return Response.ok("SUCCESS").build();
393 }
394 catch (KustvaktException e) {
395 throw responseHandler.throwit(e);
396 }
397 }
margaretha35074692021-03-26 18:11:59 +0100398
margaretha7497adf2019-11-26 13:13:57 +0100399 /**
400 * Revokes all tokens of a client for the authenticated user from
401 * a super client. This service is not part of the OAUTH2
402 * specification. It requires user authentication via
403 * authorization header, and super client
404 * via URL-encoded form parameters.
405 *
406 * @param request
407 * @param form
408 * containing client_id, super_client_id,
409 * super_client_secret
410 * @return 200 if token invalidation is successful or the given
411 * token is invalid
412 */
margaretha4993eb72023-09-27 10:54:34 +0200413 @POST
414 @Path("revoke/super/all")
415 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
416 public Response revokeAllClientTokensViaSuperClient (
417 @Context SecurityContext context,
418 @Context HttpServletRequest request,
419 @FormParam("client_id") String clientId,
420 @FormParam("super_client_id") String superClientId,
421 @FormParam("super_client_secret") String superClientSecret) {
422
423 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
424 String username = tokenContext.getUsername();
425
426 try {
427 ParameterChecker.checkStringValue("super_client_id", superClientId);
428 ParameterChecker.checkStringValue("super_client_secret",
429 superClientSecret);
margaretha35e1ca22023-11-16 22:00:01 +0100430
margaretha4993eb72023-09-27 10:54:34 +0200431 tokenService.revokeAllClientTokensViaSuperClient(username,
432 superClientId, superClientSecret, clientId);
433 return Response.ok("SUCCESS").build();
434 }
435 catch (KustvaktException e) {
436 throw responseHandler.throwit(e);
437 }
438 }
439
440 @POST
441 @Path("token/list")
442 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
margaretha35e1ca22023-11-16 22:00:01 +0100443 public List<OAuth2TokenDto> listUserToken (@Context SecurityContext context,
margaretha4993eb72023-09-27 10:54:34 +0200444 @FormParam("super_client_id") String superClientId,
445 @FormParam("super_client_secret") String superClientSecret,
446 @FormParam("client_id") String clientId, // optional
447 @FormParam("token_type") String tokenType) {
448
449 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
450 String username = tokenContext.getUsername();
451
452 try {
453 if (tokenType.equals("access_token")) {
454 return tokenService.listUserAccessToken(username, superClientId,
455 superClientSecret, clientId);
456 }
457 else if (tokenType.equals("refresh_token")) {
458 return tokenService.listUserRefreshToken(username,
459 superClientId, superClientSecret, clientId);
460 }
461 else {
462 throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
463 "Missing token_type parameter value",
464 OAuth2Error.INVALID_REQUEST);
465 }
466 }
467 catch (KustvaktException e) {
468 throw responseHandler.throwit(e);
469 }
470
471 }
margaretha0e8f4e72018-04-05 14:11:52 +0200472}