Added revocation of access tokens and authorization code when
deregistering clients, and implemented reset client secret.
Change-Id: Ice92e3759678eac4d2322ff65a0997a003de357c
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessTokenDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessTokenDao.java
index 67503e1..5564ee7 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessTokenDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessTokenDao.java
@@ -74,6 +74,18 @@
entityManager.persist(accessToken);
}
+ public AccessToken updateAccessToken (AccessToken accessToken)
+ throws KustvaktException {
+ ParameterChecker.checkObjectValue(accessToken, "access_token");
+ AccessToken cachedToken =
+ (AccessToken) this.getCacheValue(accessToken.getToken());
+ if (cachedToken != null) {
+ this.removeCacheEntry(accessToken.getToken());
+ }
+
+ accessToken = entityManager.merge(accessToken);
+ return accessToken;
+ }
public AccessToken retrieveAccessToken (String accessToken)
throws KustvaktException {
@@ -121,19 +133,6 @@
return q.getResultList();
}
- public AccessToken updateAccessToken (AccessToken accessToken)
- throws KustvaktException {
- ParameterChecker.checkObjectValue(accessToken, "access_token");
- AccessToken cachedToken =
- (AccessToken) this.getCacheValue(accessToken.getId());
- if (cachedToken != null) {
- this.removeCacheEntry(cachedToken);
- }
-
- accessToken = entityManager.merge(accessToken);
- return accessToken;
- }
-
public AccessToken retrieveAccessTokenByAnynomousToken (String token)
throws KustvaktException {
ParameterChecker.checkObjectValue(token, "token");
@@ -165,4 +164,16 @@
"Access token is not found", OAuth2Error.INVALID_TOKEN);
}
}
+
+ @SuppressWarnings("unchecked")
+ public List<AccessToken> retrieveAccessTokenByClientId (String clientId) {
+ CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ CriteriaQuery<AccessToken> query =
+ builder.createQuery(AccessToken.class);
+ Root<AccessToken> root = query.from(AccessToken.class);
+ query.select(root);
+ query.where(builder.equal(root.get(AccessToken_.clientId), clientId));
+ Query q = entityManager.createQuery(query);
+ return q.getResultList();
+ }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationCacheDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationCacheDao.java
index eed72d4..af83e16 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationCacheDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationCacheDao.java
@@ -1,6 +1,9 @@
package de.ids_mannheim.korap.oauth2.dao;
import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
import de.ids_mannheim.korap.config.KustvaktCacheable;
@@ -11,6 +14,7 @@
import de.ids_mannheim.korap.oauth2.entity.Authorization;
import de.ids_mannheim.korap.oauth2.interfaces.AuthorizationDaoInterface;
import de.ids_mannheim.korap.utils.ParameterChecker;
+import net.sf.ehcache.Element;
public class AuthorizationCacheDao extends KustvaktCacheable
implements AuthorizationDaoInterface {
@@ -69,4 +73,19 @@
return auth;
}
+ @Override
+ public List<Authorization> retrieveAuthorizationsByClientId (
+ String clientId) {
+ List<Authorization> authList = new ArrayList<>();
+
+ Map<Object, Element> map = getAllCacheElements();
+ for (Object key : map.keySet()){
+ Authorization auth = (Authorization) map.get(key).getObjectValue();
+ if (auth.getClientId().equals(clientId)){
+ authList.add(auth);
+ }
+ }
+ return authList;
+ }
+
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
index c62b130..ff82d9c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AuthorizationDao.java
@@ -1,6 +1,7 @@
package de.ids_mannheim.korap.oauth2.dao;
import java.time.ZonedDateTime;
+import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
@@ -25,14 +26,15 @@
@Transactional
@Repository
-public class AuthorizationDao implements AuthorizationDaoInterface{
+public class AuthorizationDao implements AuthorizationDaoInterface {
@PersistenceContext
private EntityManager entityManager;
public Authorization storeAuthorizationCode (String clientId, String userId,
String code, Set<AccessScope> scopes, String redirectURI,
- ZonedDateTime authenticationTime, String nonce) throws KustvaktException {
+ ZonedDateTime authenticationTime, String nonce)
+ throws KustvaktException {
ParameterChecker.checkStringValue(clientId, "client_id");
ParameterChecker.checkStringValue(userId, "userId");
ParameterChecker.checkStringValue(code, "authorization code");
@@ -85,4 +87,21 @@
authorization = entityManager.merge(authorization);
return authorization;
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<Authorization> retrieveAuthorizationsByClientId (String clientId) {
+ CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ CriteriaQuery<Authorization> query =
+ builder.createQuery(Authorization.class);
+ Root<Authorization> root = query.from(Authorization.class);
+
+ Predicate restrictions =
+ builder.equal(root.get(Authorization_.clientId), clientId);
+
+ query.select(root);
+ query.where(restrictions);
+ Query q = entityManager.createQuery(query);
+ return q.getResultList();
+ }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
index 78c438c..2b8a2eb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
@@ -84,11 +84,17 @@
}
}
- public void deregisterClient (OAuth2Client client) {
+ public void deregisterClient (OAuth2Client client) throws KustvaktException {
+ ParameterChecker.checkObjectValue(client, "client");
if (!entityManager.contains(client)) {
client = entityManager.merge(client);
}
entityManager.remove(client);
}
+ public void updateClient (OAuth2Client client) throws KustvaktException {
+ ParameterChecker.checkObjectValue(client, "client");
+ client = entityManager.merge(client);
+ }
+
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/interfaces/AuthorizationDaoInterface.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/interfaces/AuthorizationDaoInterface.java
index f9c7280..8dcde58 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/interfaces/AuthorizationDaoInterface.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/interfaces/AuthorizationDaoInterface.java
@@ -1,6 +1,7 @@
package de.ids_mannheim.korap.oauth2.interfaces;
import java.time.ZonedDateTime;
+import java.util.List;
import java.util.Set;
import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -18,4 +19,6 @@
public Authorization updateAuthorization (Authorization authorization)
throws KustvaktException;
+
+ public List<Authorization> retrieveAuthorizationsByClientId (String clientId);
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
index 8b3a639..53027f4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
@@ -5,6 +5,7 @@
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.SQLException;
+import java.util.List;
import org.apache.commons.validator.routines.UrlValidator;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,8 +20,12 @@
import de.ids_mannheim.korap.interfaces.EncryptionIface;
import de.ids_mannheim.korap.oauth2.constant.OAuth2ClientType;
import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
+import de.ids_mannheim.korap.oauth2.dao.AccessTokenDao;
import de.ids_mannheim.korap.oauth2.dao.OAuth2ClientDao;
+import de.ids_mannheim.korap.oauth2.entity.AccessToken;
+import de.ids_mannheim.korap.oauth2.entity.Authorization;
import de.ids_mannheim.korap.oauth2.entity.OAuth2Client;
+import de.ids_mannheim.korap.oauth2.interfaces.AuthorizationDaoInterface;
import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
/**
@@ -46,6 +51,10 @@
@Autowired
private OAuth2ClientDao clientDao;
@Autowired
+ private AccessTokenDao tokenDao;
+ @Autowired
+ private AuthorizationDaoInterface authorizationDao;
+ @Autowired
private AdminDao adminDao;
@Autowired
private UrlValidator redirectURIValidator;
@@ -172,7 +181,52 @@
if (adminDao.isAdmin(username)
|| client.getRegisteredBy().equals(username)) {
+
clientDao.deregisterClient(client);
+
+ // revoke all related authorization tokens
+ List<Authorization> authList = authorizationDao
+ .retrieveAuthorizationsByClientId(clientId);
+ for (Authorization authorization : authList){
+ authorization.setRevoked(true);
+ authorizationDao.updateAuthorization(authorization);
+ }
+
+ // revoke all related access tokens
+ List<AccessToken> tokens =
+ tokenDao.retrieveAccessTokenByClientId(clientId);
+ for (AccessToken token : tokens) {
+ token.setRevoked(true);
+ token.setRefreshTokenRevoked(true);
+ tokenDao.updateAccessToken(token);
+ }
+ }
+ else {
+ throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+ "Unauthorized operation for user: " + username, username);
+ }
+ }
+
+ public OAuth2ClientDto resetSecret (String clientId, String clientSecret,
+ String username) throws KustvaktException {
+
+ OAuth2Client client = authenticateClient(clientId, clientSecret);
+ if (!client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
+ throw new KustvaktException(
+ StatusCodes.NOT_ALLOWED,
+ "Operation is not allowed for public clients",
+ OAuth2Error.INVALID_REQUEST);
+ }
+ if (adminDao.isAdmin(username)
+ || client.getRegisteredBy().equals(username)) {
+
+ String secret = codeGenerator.createRandomCode();
+ String secretHashcode = encryption.secureHash(secret,
+ config.getPasscodeSaltField());
+
+ client.setSecret(secretHashcode);
+ clientDao.updateClient(client);
+ return new OAuth2ClientDto(clientId, secret);
}
else {
throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
@@ -197,15 +251,7 @@
public void authenticateClient (OAuth2Client client, String clientSecret)
throws KustvaktException {
- if (clientSecret == null) {
- if (client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
- throw new KustvaktException(
- StatusCodes.CLIENT_AUTHENTICATION_FAILED,
- "Missing parameters: client_secret",
- OAuth2Error.INVALID_REQUEST);
- }
- }
- else if (clientSecret.isEmpty()) {
+ if (clientSecret == null || clientSecret.isEmpty()) {
if (client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
throw new KustvaktException(
StatusCodes.CLIENT_AUTHENTICATION_FAILED,
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
index e78aa2a..61f8237 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
@@ -24,7 +24,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
-import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.spi.container.ResourceFilters;
import de.ids_mannheim.korap.exceptions.KustvaktException;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
index 61295e7..293685e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
@@ -29,8 +29,8 @@
/**
* Defines controllers for OAuth2 clients, namely applications
- * attempting
- * to access users' resources.
+ * performing actions such as searching and retrieving match
+ * information on behalf of users.
*
* @author margaretha
*
@@ -117,4 +117,35 @@
throw responseHandler.throwit(e);
}
}
+
+ /**
+ * Resets client secret of the given client. This controller
+ * requires client owner and client authentication. Only
+ * confidential clients are issued client secrets.
+ *
+ * @param securityContext
+ * @param clientId
+ * @param clientSecret
+ * @return a new client secret
+ */
+ @POST
+ @Path("reset")
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+ @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+ public OAuth2ClientDto resetClientSecret (
+ @Context SecurityContext securityContext,
+ @FormParam("client_id") String clientId,
+ @FormParam("client_secret") String clientSecret) {
+ TokenContext context =
+ (TokenContext) securityContext.getUserPrincipal();
+ try {
+ return clientService.resetSecret(clientId, clientSecret,
+ context.getUsername());
+ }
+ catch (KustvaktException e) {
+ throw responseHandler.throwit(e);
+ }
+ }
+
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
index 88603cc..d0a6cf6 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/AuthenticationFilter.java
@@ -75,7 +75,8 @@
context = authenticationManager.getTokenContext(
TokenType.BEARER, authData.getToken(), host,
ua);
- if (request.getPath().startsWith("vc/access")
+ if (request.getPath().startsWith("oauth2")
+ || request.getPath().startsWith("vc/access")
|| request.getPath().startsWith("vc/delete")
|| request.getPath().startsWith("group")
|| request.getPath().startsWith("user")) {
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
index b5f89a5..ffecbb3 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
@@ -4,6 +4,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import java.net.URI;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
@@ -12,6 +13,8 @@
import org.apache.http.entity.ContentType;
import org.junit.Test;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.util.UriComponentsBuilder;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.net.HttpHeaders;
@@ -52,7 +55,7 @@
}
}
- private ClientResponse testRegisterConfidentialClient ()
+ private ClientResponse registerConfidentialClient ()
throws KustvaktException {
OAuth2ClientJson json = new OAuth2ClientJson();
@@ -71,8 +74,8 @@
}
@Test
- public void testRegisterClientNonUniqueURL () throws KustvaktException {
- ClientResponse response = testRegisterConfidentialClient();
+ public void testRegisterConfidentialClient () throws KustvaktException {
+ ClientResponse response = registerConfidentialClient();
String entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
JsonNode node = JsonUtils.readTree(entity);
@@ -81,14 +84,22 @@
assertNotNull(clientId);
assertNotNull(clientSecret);
- response = testRegisterConfidentialClient();
- assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- node = JsonUtils.readTree(response.getEntity(String.class));
- assertEquals(OAuth2Error.INVALID_REQUEST, node.at("/error").asText());
+ testRegisterClientNonUniqueURL();
+
+ String newclientSecret =
+ testResetConfidentialClientSecret(clientId, clientSecret);
testDeregisterConfidentialClientMissingSecret(clientId);
- testDeregisterClientIncorrectCredentials(clientId);
- testDeregisterConfidentialClient(clientId, clientSecret);
+ testDeregisterClientIncorrectCredentials(clientId, clientSecret);
+ testDeregisterConfidentialClient(clientId, newclientSecret);
+ }
+
+
+ private void testRegisterClientNonUniqueURL () throws KustvaktException {
+ ClientResponse response = registerConfidentialClient();
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(OAuth2Error.INVALID_REQUEST, node.at("/error").asText());
}
@Test
@@ -122,29 +133,6 @@
}
@Test
- public void testRegisterNativeClient () throws UniformInterfaceException,
- ClientHandlerException, KustvaktException {
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("NativeClient");
- json.setType(OAuth2ClientType.PUBLIC);
- json.setUrl("http://korap.ids-mannheim.de/native");
- json.setRedirectURI("https://korap.ids-mannheim.de/native/redirect");
- json.setDescription("This is a native test client.");
-
- ClientResponse response = resource().path("oauth2").path("client")
- .path("register")
- .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
- .createBasicAuthorizationHeaderValue(username, "pass"))
- .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
- .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
- .entity(json).post(ClientResponse.class);
-
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
- // EM: need to check native
- }
-
- @Test
public void testRegisterDesktopApp () throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
OAuth2ClientJson json = new OAuth2ClientJson();
@@ -166,6 +154,117 @@
String clientId = node.at("/client_id").asText();
assertNotNull(clientId);
assertTrue(node.at("/client_secret").isMissingNode());
+
+ testResetPublicClientSecret(clientId);
+ }
+
+ @Test
+ public void testRegisterNativeClient () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ OAuth2ClientJson json = new OAuth2ClientJson();
+ json.setName("NativeClient");
+ json.setType(OAuth2ClientType.PUBLIC);
+ json.setUrl("http://korap.ids-mannheim.de/native");
+ json.setRedirectURI("https://korap.ids-mannheim.de/native/redirect");
+ json.setDescription("This is a native test client.");
+
+ ClientResponse response = resource().path("oauth2").path("client")
+ .path("register")
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue(username, "pass"))
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+ .entity(json).post(ClientResponse.class);
+
+ String entity = response.getEntity(String.class);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ JsonNode node = JsonUtils.readTree(entity);
+ String clientId = node.at("/client_id").asText();
+
+ // EM: need to check native
+
+ testAccessTokenAfterDeregistration(clientId);
+ }
+
+ private void testAccessTokenAfterDeregistration (String clientId)
+ throws KustvaktException {
+ String code = requestAuthorizationCode(clientId, "");
+ ClientResponse response = requestAccessToken(code, clientId, "");
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ String accessToken = node.at("/access_token").asText();
+
+ response = searchWithAccessToken(accessToken);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ code = requestAuthorizationCode(clientId, "");
+ testDeregisterPublicClient(clientId);
+
+ response = requestAccessToken(code, clientId, "");
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+ node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(OAuth2Error.INVALID_CLIENT.toString(),
+ node.at("/error").asText());
+
+ response = searchWithAccessToken(accessToken);
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+ node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(StatusCodes.INVALID_ACCESS_TOKEN,
+ node.at("/errors/0/0").asInt());
+ assertEquals("Access token has been revoked",
+ node.at("/errors/0/1").asText());
+
+ }
+
+ private String requestAuthorizationCode (String clientId,
+ String clientSecret) throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("response_type", "code");
+ form.add("client_id", clientId);
+ form.add("client_secret", clientSecret);
+
+ ClientResponse response = resource().path("oauth2").path("authorize")
+ .header(Attributes.AUTHORIZATION,
+ HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue("dory",
+ "password"))
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+
+ assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
+ response.getStatus());
+ URI redirectUri = response.getLocation();
+ MultiValueMap<String, String> params = UriComponentsBuilder
+ .fromUri(redirectUri).build().getQueryParams();
+ return params.getFirst("code");
+ }
+
+ private ClientResponse requestAccessToken (String code, String clientId,
+ String clientSecret) throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("grant_type", "authorization_code");
+ form.add("client_id", clientId);
+ form.add("client_secret", clientSecret);
+ form.add("code", code);
+
+ ClientResponse response = resource().path("oauth2").path("token")
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+
+ return response;
+ }
+
+ private ClientResponse searchWithAccessToken (String accessToken) {
+ ClientResponse response = resource().path("search")
+ .queryParam("q", "Wasser").queryParam("ql", "poliqarp")
+ .header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .get(ClientResponse.class);
+
+ return response;
}
private void testDeregisterPublicClientMissingUserAuthentication (
@@ -247,12 +346,12 @@
node.at("/error_description").asText());
}
- private void testDeregisterClientIncorrectCredentials (String clientId)
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ private void testDeregisterClientIncorrectCredentials (String clientId,
+ String clientSecret) throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
- form.add("client_secret", "xxx");
+ form.add("client_secret", clientSecret);
ClientResponse response = resource().path("oauth2").path("client")
.path("deregister").path(clientId)
@@ -272,4 +371,53 @@
checkWWWAuthenticateHeader(response);
}
+
+ private void testResetPublicClientSecret (String clientId)
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("client_id", clientId);
+
+ ClientResponse response = resource().path("oauth2").path("client")
+ .path("reset")
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue(username, "pass"))
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+
+ String entity = response.getEntity(String.class);
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(OAuth2Error.INVALID_REQUEST, node.at("/error").asText());
+ assertEquals("Operation is not allowed for public clients",
+ node.at("/error_description").asText());
+ }
+
+ private String testResetConfidentialClientSecret (String clientId,
+ String clientSecret) throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("client_id", clientId);
+ form.add("client_secret", clientSecret);
+
+ ClientResponse response = resource().path("oauth2").path("client")
+ .path("reset")
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue(username, "pass"))
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+
+ String entity = response.getEntity(String.class);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals(clientId, node.at("/client_id").asText());
+
+ String newClientSecret = node.at("/client_secret").asText();
+ assertTrue(!clientSecret.equals(newClientSecret));
+
+ return newClientSecret;
+ }
}