blob: 60dd425596d238a5ae1e42ce96e69e2d3db4a97d [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 requestURI = builder.build();
margaretha35e1ca22023-11-16 22:00:01 +0100270
margaretha7ac20b12023-09-27 09:40:16 +0200271 try {
margaretha35e1ca22023-11-16 22:00:01 +0100272 AuthorizationGrant authGrant = AuthorizationGrant.parse(form);
273
margaretha7ac20b12023-09-27 09:40:16 +0200274 ClientAuthentication clientAuth = null;
275 String authorizationHeader = request.getHeader("Authorization");
margaretha35e1ca22023-11-16 22:00:01 +0100276 if (authorizationHeader != null
277 && !authorizationHeader.isEmpty()) {
margaretha7ac20b12023-09-27 09:40:16 +0200278 clientAuth = ClientSecretBasic.parse(authorizationHeader);
279 }
280 else if (authGrant instanceof ClientCredentialsGrant) {
281 // this doesn't allow public clients
282 clientAuth = ClientSecretPost.parse(form);
283 }
margaretha35e1ca22023-11-16 22:00:01 +0100284
margaretha7ac20b12023-09-27 09:40:16 +0200285 TokenRequest tokenRequest = null;
margaretha35e1ca22023-11-16 22:00:01 +0100286 if (clientAuth != null) {
margaretha7ac20b12023-09-27 09:40:16 +0200287 ClientAuthenticationMethod method = clientAuth.getMethod();
margaretha35e1ca22023-11-16 22:00:01 +0100288 if (method.equals(
289 ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) {
margaretha7ac20b12023-09-27 09:40:16 +0200290 ClientSecretBasic basic = (ClientSecretBasic) clientAuth;
291 clientSecret = basic.getClientSecret().getValue();
292 clientId = basic.getClientID().getValue();
293 }
margaretha35e1ca22023-11-16 22:00:01 +0100294 else if (method.equals(
295 ClientAuthenticationMethod.CLIENT_SECRET_POST)) {
margaretha7ac20b12023-09-27 09:40:16 +0200296 ClientSecretPost post = (ClientSecretPost) clientAuth;
297 clientSecret = post.getClientSecret().getValue();
298 clientId = post.getClientID().getValue();
299 }
margaretha35e1ca22023-11-16 22:00:01 +0100300
301 tokenRequest = new TokenRequest(requestURI, clientAuth,
margaretha7ac20b12023-09-27 09:40:16 +0200302 AuthorizationGrant.parse(form),
303 Scope.parse(form.getFirst("scope")));
304 }
305 else {
306 // requires ClientAuthentication for client_credentials grant
307 tokenRequest = new TokenRequest(requestURI,
margaretha35e1ca22023-11-16 22:00:01 +0100308 new ClientID(clientId),
309 AuthorizationGrant.parse(form),
310 Scope.parse(form.getFirst("scope")));
margaretha7ac20b12023-09-27 09:40:16 +0200311 }
margaretha35e1ca22023-11-16 22:00:01 +0100312
313 AccessTokenResponse r = tokenService.requestAccessToken(
314 tokenRequest, clientId, clientSecret);
margarethab8a9d4e2023-10-25 12:00:10 +0200315 return responseHandler.createResponse(r);
margaretha7ac20b12023-09-27 09:40:16 +0200316 }
317 catch (ParseException | IllegalArgumentException e) {
318 throw new KustvaktException(StatusCodes.INVALID_REQUEST,
margaretha35e1ca22023-11-16 22:00:01 +0100319 e.getMessage(), OAuth2Error.INVALID_REQUEST);
margaretha7ac20b12023-09-27 09:40:16 +0200320 }
margaretha35e1ca22023-11-16 22:00:01 +0100321
margaretha7ac20b12023-09-27 09:40:16 +0200322 }
323 catch (KustvaktException e) {
324 throw responseHandler.throwit(e);
325 }
margaretha7ac20b12023-09-27 09:40:16 +0200326 }
margarethaec247dd2018-06-12 21:55:46 +0200327
margarethadc515072018-08-03 17:01:19 +0200328 /**
margaretha1ef36bd2018-08-14 18:17:05 +0200329 * Revokes either an access token or a refresh token. Revoking a
330 * refresh token also revokes all access token associated with the
331 * refresh token.
margarethadc515072018-08-03 17:01:19 +0200332 *
333 * RFC 7009
334 * Client authentication for confidential client
335 *
336 * @param request
337 * @param form
margaretha1ef36bd2018-08-14 18:17:05 +0200338 * containing
339 * client_id,
340 * client_secret (required for confidential clients),
341 * token,
342 * token_type (optional)
margarethadc515072018-08-03 17:01:19 +0200343 * @return 200 if token invalidation is successful or the given
344 * token is invalid
345 */
margaretha4993eb72023-09-27 10:54:34 +0200346 @POST
347 @Path("revoke")
margaretha35e1ca22023-11-16 22:00:01 +0100348 @ResourceFilters({ APIVersionFilter.class })
margaretha4993eb72023-09-27 10:54:34 +0200349 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
350 public Response revokeAccessToken (@Context HttpServletRequest request,
351 @FormParam("client_id") String clientId,
352 @FormParam("client_secret") String clientSecret,
353 @FormParam("token") String token,
354 @FormParam("token_type") String tokenType) {
355
356 try {
357 ParameterChecker.checkStringValue("client_id", clientId);
358 ParameterChecker.checkStringValue("token", token);
margaretha35e1ca22023-11-16 22:00:01 +0100359 tokenService.revokeToken(clientId, clientSecret, token, tokenType);
360
margaretha4993eb72023-09-27 10:54:34 +0200361 return Response.ok("SUCCESS").build();
362 }
363 catch (KustvaktException e) {
364 throw responseHandler.throwit(e);
365 }
366 }
367
368 @POST
369 @Path("revoke/super")
370 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
371 public Response revokeTokenViaSuperClient (@Context SecurityContext context,
372 @Context HttpServletRequest request,
373 @FormParam("super_client_id") String superClientId,
374 @FormParam("super_client_secret") String superClientSecret,
375 @FormParam("token") String token) {
376
377 try {
378 ParameterChecker.checkStringValue("super_client_id", superClientId);
379 ParameterChecker.checkStringValue("super_client_secret",
380 superClientSecret);
381 ParameterChecker.checkStringValue("token", token);
margaretha35e1ca22023-11-16 22:00:01 +0100382
383 TokenContext tokenContext = (TokenContext) context
384 .getUserPrincipal();
margaretha4993eb72023-09-27 10:54:34 +0200385 String username = tokenContext.getUsername();
margaretha35e1ca22023-11-16 22:00:01 +0100386
margaretha4993eb72023-09-27 10:54:34 +0200387 tokenService.revokeTokensViaSuperClient(username, superClientId,
388 superClientSecret, token);
389 return Response.ok("SUCCESS").build();
390 }
391 catch (KustvaktException e) {
392 throw responseHandler.throwit(e);
393 }
394 }
margaretha35074692021-03-26 18:11:59 +0100395
margaretha7497adf2019-11-26 13:13:57 +0100396 /**
397 * Revokes all tokens of a client for the authenticated user from
398 * a super client. This service is not part of the OAUTH2
399 * specification. It requires user authentication via
400 * authorization header, and super client
401 * via URL-encoded form parameters.
402 *
403 * @param request
404 * @param form
405 * containing client_id, super_client_id,
406 * super_client_secret
407 * @return 200 if token invalidation is successful or the given
408 * token is invalid
409 */
margaretha4993eb72023-09-27 10:54:34 +0200410 @POST
411 @Path("revoke/super/all")
412 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
413 public Response revokeAllClientTokensViaSuperClient (
414 @Context SecurityContext context,
415 @Context HttpServletRequest request,
416 @FormParam("client_id") String clientId,
417 @FormParam("super_client_id") String superClientId,
418 @FormParam("super_client_secret") String superClientSecret) {
419
420 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
421 String username = tokenContext.getUsername();
422
423 try {
424 ParameterChecker.checkStringValue("super_client_id", superClientId);
425 ParameterChecker.checkStringValue("super_client_secret",
426 superClientSecret);
margaretha35e1ca22023-11-16 22:00:01 +0100427
margaretha4993eb72023-09-27 10:54:34 +0200428 tokenService.revokeAllClientTokensViaSuperClient(username,
429 superClientId, superClientSecret, clientId);
430 return Response.ok("SUCCESS").build();
431 }
432 catch (KustvaktException e) {
433 throw responseHandler.throwit(e);
434 }
435 }
436
437 @POST
438 @Path("token/list")
439 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
margaretha35e1ca22023-11-16 22:00:01 +0100440 public List<OAuth2TokenDto> listUserToken (@Context SecurityContext context,
margaretha4993eb72023-09-27 10:54:34 +0200441 @FormParam("super_client_id") String superClientId,
442 @FormParam("super_client_secret") String superClientSecret,
443 @FormParam("client_id") String clientId, // optional
444 @FormParam("token_type") String tokenType) {
445
446 TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
447 String username = tokenContext.getUsername();
448
449 try {
450 if (tokenType.equals("access_token")) {
451 return tokenService.listUserAccessToken(username, superClientId,
452 superClientSecret, clientId);
453 }
454 else if (tokenType.equals("refresh_token")) {
455 return tokenService.listUserRefreshToken(username,
456 superClientId, superClientSecret, clientId);
457 }
458 else {
459 throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
460 "Missing token_type parameter value",
461 OAuth2Error.INVALID_REQUEST);
462 }
463 }
464 catch (KustvaktException e) {
465 throw responseHandler.throwit(e);
466 }
467
468 }
margaretha0e8f4e72018-04-05 14:11:52 +0200469}