Added more parameter checks and OAuth2Client web-service tests.
Change-Id: I310ec386cc12c527d1b051e104e5ea95777189f4
diff --git a/full/Changes b/full/Changes
index 18e0aea..807c83e 100644
--- a/full/Changes
+++ b/full/Changes
@@ -3,6 +3,9 @@
2022-03-03
- Removed VCLoader.
- Added foreign keys to the DB tables of access and refresh token scopes.
+2022-03-07
+ - Added more parameter checks and OAuth2Client web-service tests.
+
# version 0.65.1
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 64cafd6..51f8022 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
@@ -83,6 +83,7 @@
String registeredBy) throws KustvaktException {
try {
ParameterChecker.checkNameValue(clientJson.getName(), "client_name");
+ ParameterChecker.checkObjectValue(clientJson.getType(), "client_type");
}
catch (KustvaktException e) {
throw new KustvaktException(e.getStatusCode(), e.getMessage(),
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/QueryService.java b/full/src/main/java/de/ids_mannheim/korap/service/QueryService.java
index 3bda7f3..750dba4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/QueryService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/QueryService.java
@@ -627,6 +627,8 @@
String createdBy, QueryType queryType, String fieldName)
throws KustvaktException {
+ ParameterChecker.checkStringValue(fieldName, "fieldName");
+
if (!adminDao.isAdmin(username)) {
throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
"Unauthorized operation for user: " + username, username);
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 05d683e..f688b31 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
@@ -1,9 +1,9 @@
package de.ids_mannheim.korap.web.controller;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
import java.io.IOException;
import java.io.InputStream;
@@ -61,14 +61,30 @@
}
}
}
-
- private ClientResponse registerClient (String username,
+
+ private OAuth2ClientJson createOAuth2ClientJson (String name,
+ OAuth2ClientType type, String description) {
+ OAuth2ClientJson client = new OAuth2ClientJson();
+ if (name != null) {
+ client.setName(name);
+ }
+ client.setType(type);
+ if (description != null) {
+ client.setDescription(description);
+ }
+ return client;
+
+ }
+
+ private ClientResponse registerClient (String username,
OAuth2ClientJson json) throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
return resource().path(API_VERSION).path("oauth2").path("client")
.path("register")
- .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
- .createBasicAuthorizationHeaderValue(username, "password"))
+ .header(Attributes.AUTHORIZATION,
+ HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue(username,
+ "password"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
.entity(json).post(ClientResponse.class);
@@ -116,20 +132,22 @@
// confidential client
clientInfo = retrieveClientInfo(confidentialClientId, "system");
assertEquals(confidentialClientId, clientInfo.at("/id").asText());
- assertEquals("non super confidential client", clientInfo.at("/name").asText());
+ assertEquals("non super confidential client",
+ clientInfo.at("/name").asText());
assertNotNull(clientInfo.at("/url"));
- assertEquals(false,clientInfo.at("/is_super").asBoolean());
+ assertEquals(false, clientInfo.at("/is_super").asBoolean());
assertEquals("CONFIDENTIAL", clientInfo.at("/type").asText());
-
+
// super client
clientInfo = retrieveClientInfo(superClientId, "system");
assertEquals(superClientId, clientInfo.at("/id").asText());
- assertEquals("super confidential client", clientInfo.at("/name").asText());
+ assertEquals("super confidential client",
+ clientInfo.at("/name").asText());
assertNotNull(clientInfo.at("/url"));
assertEquals("CONFIDENTIAL", clientInfo.at("/type").asText());
assertTrue(clientInfo.at("/is_super").asBoolean());
}
-
+
@Test
public void testRegisterConfidentialClient () throws KustvaktException {
ClientResponse response = registerConfidentialClient();
@@ -142,7 +160,7 @@
assertNotNull(clientSecret);
assertFalse(clientId.contains("a"));
-
+
testResetConfidentialClientSecret(clientId, clientSecret);
testDeregisterConfidentialClient(clientId);
}
@@ -151,49 +169,91 @@
public void testRegisterClientNameTooShort ()
throws UniformInterfaceException, ClientHandlerException,
KustvaktException {
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("R");
- json.setType(OAuth2ClientType.PUBLIC);
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson("R", OAuth2ClientType.PUBLIC, null);
- ClientResponse response = registerClient(username, json);
+ ClientResponse response = registerClient(username, clientJson);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
assertEquals("client_name must contain at least 3 characters",
node.at("/error_description").asText());
- assertEquals("invalid_request",
- node.at("/error").asText());
+ assertEquals("invalid_request", node.at("/error").asText());
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
}
-
+
+ @Test
+ public void testRegisterClientEmptyName () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson("", OAuth2ClientType.PUBLIC, null);
+
+ ClientResponse response = registerClient(username, clientJson);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals("client_name must contain at least 3 characters",
+ node.at("/error_description").asText());
+ assertEquals("invalid_request", node.at("/error").asText());
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void testRegisterClientMissingName ()
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson(null, OAuth2ClientType.PUBLIC, null);
+
+ ClientResponse response = registerClient(username, clientJson);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals("client_name is null",
+ node.at("/error_description").asText());
+ assertEquals("invalid_request", node.at("/error").asText());
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+
@Test
public void testRegisterClientMissingDescription ()
throws UniformInterfaceException, ClientHandlerException,
KustvaktException {
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("R client");
- json.setType(OAuth2ClientType.PUBLIC);
+ OAuth2ClientJson clientJson = createOAuth2ClientJson("R client",
+ OAuth2ClientType.PUBLIC, null);
- ClientResponse response = registerClient(username, json);
+ ClientResponse response = registerClient(username, clientJson);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
assertEquals("client_description is null",
node.at("/error_description").asText());
- assertEquals("invalid_request",
- node.at("/error").asText());
+ assertEquals("invalid_request", node.at("/error").asText());
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
}
-
+
+ @Test
+ public void testRegisterClientMissingType ()
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson("R client", null, null);
+
+ ClientResponse response = registerClient(username, clientJson);
+ String entity = response.getEntity(String.class);
+ JsonNode node = JsonUtils.readTree(entity);
+ assertEquals("client_type is null",
+ node.at("/error_description").asText());
+ assertEquals("invalid_request", node.at("/error").asText());
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+
@Test
public void testRegisterPublicClient () throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("OAuth2PublicClient");
- json.setType(OAuth2ClientType.PUBLIC);
- json.setUrl("http://test.public.client.com");
- json.setRedirectURI("https://test.public.client.com/redirect");
- json.setDescription("This is a public test client.");
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson("OAuth2PublicClient",
+ OAuth2ClientType.PUBLIC, "A public test client.");
+ clientJson.setUrl("http://test.public.client.com");
+ clientJson.setRedirectURI("https://test.public.client.com/redirect");
- ClientResponse response = registerClient(username, json);
+ ClientResponse response = registerClient(username, clientJson);
String entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -202,10 +262,45 @@
assertNotNull(clientId);
assertTrue(node.at("/client_secret").isMissingNode());
+ testRegisterClientUnauthorizedScope(clientId);
testResetPublicClientSecret(clientId);
- testAccessTokenAfterDeregistration(clientId, null,null);
+ testAccessTokenAfterDeregistration(clientId, null, null);
}
-
+
+ private void testRegisterClientUnauthorizedScope (String clientId)
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
+
+ String userAuthHeader = HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue("dory", "password");
+ String code = requestAuthorizationCode(clientId, "", null,
+ userAuthHeader, null);
+ ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
+ clientId, clientSecret, code, null);
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+
+ assertEquals("match_info search", node.at("/scope").asText());
+
+ String accessToken = node.at("/access_token").asText();
+
+ OAuth2ClientJson clientJson = createOAuth2ClientJson("R client",
+ OAuth2ClientType.PUBLIC, null);
+
+ response = resource().path(API_VERSION).path("oauth2").path("client")
+ .path("register")
+ .header(Attributes.AUTHORIZATION, "Bearer " + accessToken)
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+ .entity(clientJson).post(ClientResponse.class);
+
+ String entity = response.getEntity(String.class);
+ node = JsonUtils.readTree(entity);
+ assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+ node.at("/errors/0/0").asInt());
+ assertEquals("Scope register_client is not authorized",
+ node.at("/errors/0/1").asText());
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+ }
+
@Test
public void testRegisterClientUsingPlainJson ()
throws UniformInterfaceException, ClientHandlerException,
@@ -234,16 +329,15 @@
testResetPublicClientSecret(clientId);
testAccessTokenAfterDeregistration(clientId, null, null);
}
-
+
@Test
public void testRegisterDesktopApp () throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("OAuth2DesktopClient");
- json.setType(OAuth2ClientType.PUBLIC);
- json.setDescription("This is a desktop test client.");
+ OAuth2ClientJson clientJson = createOAuth2ClientJson(
+ "OAuth2DesktopClient", OAuth2ClientType.PUBLIC,
+ "This is a desktop test client.");
- ClientResponse response = registerClient(username, json);
+ ClientResponse response = registerClient(username, clientJson);
String entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -254,20 +348,20 @@
testDeregisterPublicClientMissingUserAuthentication(clientId);
testDeregisterPublicClientMissingId();
- testDeregisterPublicClient(clientId,username);
+ testDeregisterPublicClient(clientId, username);
}
@Test
- public void testRegisterMultipleDesktopApps () throws UniformInterfaceException,
- ClientHandlerException, KustvaktException {
+ public void testRegisterMultipleDesktopApps ()
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
// First client
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName("OAuth2DesktopClient1");
- json.setType(OAuth2ClientType.PUBLIC);
- json.setDescription("This is a desktop test client.");
+ OAuth2ClientJson clientJson =
+ createOAuth2ClientJson("OAuth2DesktopClient1",
+ OAuth2ClientType.PUBLIC, "A desktop test client.");
- ClientResponse response = registerClient(username, json);
+ ClientResponse response = registerClient(username, clientJson);
String entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -277,12 +371,10 @@
assertTrue(node.at("/client_secret").isMissingNode());
// Second client
- json = new OAuth2ClientJson();
- json.setName("OAuth2DesktopClient2");
- json.setType(OAuth2ClientType.PUBLIC);
- json.setDescription("This is another desktop test client.");
+ clientJson = createOAuth2ClientJson("OAuth2DesktopClient2",
+ OAuth2ClientType.PUBLIC, "Another desktop test client.");
- response = registerClient(username, json);
+ response = registerClient(username, clientJson);
entity = response.getEntity(String.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -298,7 +390,7 @@
testAccessTokenAfterDeregistration(clientId2, null,
"https://OAuth2DesktopClient2.com");
}
-
+
private void testAccessTokenAfterDeregistration (String clientId,
String clientSecret, String redirectUri) throws KustvaktException {
String userAuthHeader = HttpAuthorizationHandler
@@ -360,7 +452,8 @@
.createBasicAuthorizationHeaderValue(username, "pass"))
.delete(ClientResponse.class);
- assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus());
+ assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(),
+ response.getStatus());
}
private void testDeregisterPublicClient (String clientId, String username)
@@ -530,14 +623,15 @@
assertEquals(Status.OK.getStatusCode(), response.getStatus());
String entity = response.getEntity(String.class);
-// System.out.println(entity);
+ // System.out.println(entity);
JsonNode node = JsonUtils.readTree(entity);
assertEquals(2, node.size());
assertEquals(confidentialClientId, node.at("/0/client_id").asText());
assertEquals(publicClientId, node.at("/1/client_id").asText());
-
- assertEquals("non super confidential client",node.at("/0/client_name").asText());
- assertEquals("CONFIDENTIAL",node.at("/0/client_type").asText());
+
+ assertEquals("non super confidential client",
+ node.at("/0/client_name").asText());
+ assertEquals("CONFIDENTIAL", node.at("/0/client_type").asText());
assertFalse(node.at("/0/client_url").isMissingNode());
assertFalse(node.at("/0/client_description").isMissingNode());
}
@@ -555,8 +649,8 @@
assertEquals(Status.OK.getStatusCode(), response.getStatus());
// client 1
- String code = requestAuthorizationCode(publicClientId, "",
- null, userAuthHeader);
+ String code = requestAuthorizationCode(publicClientId, "", null,
+ userAuthHeader);
response = requestTokenWithAuthorizationCodeAndForm(publicClientId, "",
code);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -576,62 +670,62 @@
testListAuthorizedClientWithMultipleRefreshTokens(userAuthHeader);
testListAuthorizedClientWithMultipleAccessTokens(userAuthHeader);
testListWithClientsFromAnotherUser(userAuthHeader);
-
+
// revoke client 1
testRevokeAllTokenViaSuperClient(publicClientId, userAuthHeader,
accessToken);
-
+
// revoke client 2
node = JsonUtils.readTree(response.getEntity(String.class));
accessToken = node.at("/access_token").asText();
refreshToken = node.at("/refresh_token").asText();
testRevokeAllTokenViaSuperClient(confidentialClientId, userAuthHeader,
accessToken);
- testRequestTokenWithRevokedRefreshToken(confidentialClientId, clientSecret,
- refreshToken);
+ testRequestTokenWithRevokedRefreshToken(confidentialClientId,
+ clientSecret, refreshToken);
}
private void testListAuthorizedClientWithMultipleRefreshTokens (
String userAuthHeader) throws KustvaktException {
// client 2
- String code = requestAuthorizationCode(confidentialClientId, clientSecret,
- null, userAuthHeader);
+ String code = requestAuthorizationCode(confidentialClientId,
+ clientSecret, null, userAuthHeader);
ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
confidentialClientId, clientSecret, code);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
+
requestAuthorizedClientList(userAuthHeader);
}
-
+
private void testListAuthorizedClientWithMultipleAccessTokens (
String userAuthHeader) throws KustvaktException {
// client 1
- String code = requestAuthorizationCode(publicClientId, "",
- null, userAuthHeader);
+ String code = requestAuthorizationCode(publicClientId, "", null,
+ userAuthHeader);
ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
publicClientId, "", code);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
+
requestAuthorizedClientList(userAuthHeader);
}
-
- private void testListWithClientsFromAnotherUser (
- String userAuthHeader) throws KustvaktException {
+
+ private void testListWithClientsFromAnotherUser (String userAuthHeader)
+ throws KustvaktException {
String aaaAuthHeader = HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("aaa", "pwd");
-
+
// client 1
- String code = requestAuthorizationCode(publicClientId, "",
- null, aaaAuthHeader);
+ String code = requestAuthorizationCode(publicClientId, "", null,
+ aaaAuthHeader);
ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
publicClientId, "", code);
-
+
JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
String accessToken1 = node.at("/access_token").asText();
-
+
// client 2
code = requestAuthorizationCode(confidentialClientId, clientSecret,
null, aaaAuthHeader);
@@ -649,8 +743,8 @@
accessToken1);
testRevokeAllTokenViaSuperClient(confidentialClientId, aaaAuthHeader,
accessToken2);
- testRequestTokenWithRevokedRefreshToken(confidentialClientId, clientSecret,
- refreshToken);
+ testRequestTokenWithRevokedRefreshToken(confidentialClientId,
+ clientSecret, refreshToken);
}
private void testRevokeAllTokenViaSuperClient (String clientId,
@@ -683,19 +777,16 @@
assertEquals("Access token is invalid",
node.at("/errors/0/1").asText());
}
-
+
@Test
- public void testListRegisteredClients ()
- throws KustvaktException {
-
+ public void testListRegisteredClients () throws KustvaktException {
+
String clientName = "OAuth2DoryClient";
- OAuth2ClientJson json = new OAuth2ClientJson();
- json.setName(clientName);
- json.setType(OAuth2ClientType.PUBLIC);
- json.setDescription("This is dory client.");
+ OAuth2ClientJson json = createOAuth2ClientJson(clientName,
+ OAuth2ClientType.PUBLIC, "Dory's client.");
registerClient("dory", json);
-
+
MultivaluedMap<String, String> form = new MultivaluedMapImpl();
form.add("super_client_id", superClientId);
form.add("super_client_secret", clientSecret);
@@ -711,10 +802,11 @@
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
-
+
assertEquals(1, node.size());
assertEquals(clientName, node.at("/0/client_name").asText());
- assertEquals(OAuth2ClientType.PUBLIC.name(), node.at("/0/client_type").asText());
+ assertEquals(OAuth2ClientType.PUBLIC.name(),
+ node.at("/0/client_type").asText());
String clientId = node.at("/0/client_id").asText();
testDeregisterPublicClient(clientId, "dory");
}