Fixed sharing unknown VC, updating corpusQuery, and handling non-unique
group name and unknown VC access.
Change-Id: Ie8a49e2616a6fbb947b4200b8e64763de9ea4d8f
diff --git a/full/Changes b/full/Changes
index 7620c38..1633dbb 100644
--- a/full/Changes
+++ b/full/Changes
@@ -7,6 +7,9 @@
11/04/2019
- Fixed unknown authentication scheme, missing VC entity, and parameter
checker (margaretha)
+ - Fixed sharing unknown VC, updating corpusQuery, and handling non-
+ unique group name and unknown VC access (margaretha)
+
# version 0.61.6
04/02/2019
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
index db49626..3b372ab 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
@@ -24,6 +24,8 @@
import de.ids_mannheim.korap.entity.VirtualCorpusAccess_;
import de.ids_mannheim.korap.entity.VirtualCorpus_;
import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
import de.ids_mannheim.korap.utils.ParameterChecker;
/**
@@ -57,7 +59,14 @@
query.where(
builder.equal(access.get(VirtualCorpusAccess_.id), accessId));
Query q = entityManager.createQuery(query);
- return (VirtualCorpusAccess) q.getSingleResult();
+ try{
+ return (VirtualCorpusAccess) q.getSingleResult();
+ }
+ catch (NoResultException e) {
+ throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
+ "Virtual corpus access is not found",
+ String.valueOf(accessId));
+ }
}
// for vca admins
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java b/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
index e094c33..e06e9b2 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -1,5 +1,6 @@
package de.ids_mannheim.korap.service;
+import java.sql.SQLException;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
@@ -214,8 +215,26 @@
public void createUserGroup (UserGroupJson groupJson, String createdBy)
throws KustvaktException {
- int groupId = userGroupDao.createGroup(groupJson.getName(), createdBy,
- UserGroupStatus.ACTIVE);
+ int groupId=0;
+ try {
+ groupId = userGroupDao.createGroup(groupJson.getName(), createdBy,
+ UserGroupStatus.ACTIVE);
+ }
+ // handle DB exceptions, e.g. unique constraint
+ catch (Exception e) {
+ Throwable cause = e;
+ Throwable lastCause = null;
+ while ((cause = cause.getCause()) != null
+ && !cause.equals(lastCause)) {
+ if (cause instanceof SQLException) {
+ break;
+ }
+ lastCause = cause;
+ }
+ throw new KustvaktException(StatusCodes.DB_INSERT_FAILED,
+ cause.getMessage());
+ }
+
UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
if (groupJson.getMembers() != null){
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
index c0ba90b..187b738 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
@@ -255,7 +255,7 @@
String koralQuery = null;
CorpusAccess requiredAccess = null;
String corpusQuery = newVC.getCorpusQuery();
- if (corpusQuery != null && corpusQuery.isEmpty()) {
+ if (corpusQuery != null && !corpusQuery.isEmpty()) {
koralQuery = serializeCorpusQuery(corpusQuery);
requiredAccess = determineRequiredAccess(newVC.isCached(), vcName,
koralQuery);
@@ -428,6 +428,12 @@
String groupName) throws KustvaktException {
VirtualCorpus vc = vcDao.retrieveVCByName(vcName, createdBy);
+ if (vc == null){
+ String vcCode = createdBy + "/" + vcName;
+ throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
+ "Virtual corpus "+ vcCode+" is not found.",
+ String.valueOf(vcCode));
+ }
if (!username.equals(vc.getCreatedBy())
&& !adminDao.isAdmin(username)) {
throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
index ce5535a..53adca4 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
@@ -119,15 +119,17 @@
public void testRetrieveSystemVCInfo () throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
- JsonNode node = testSearchVC("VirtualCorpusControllerTest", "system", "system VC");
+ JsonNode node = testSearchVC("VirtualCorpusControllerTest", "system",
+ "system VC");
assertEquals("system VC", node.at("/name").asText());
assertEquals(VirtualCorpusType.SYSTEM.displayName(),
node.at("/type").asText());
}
@Test
- public void testRetrieveOwnerPrivateVCInfo () throws UniformInterfaceException,
- ClientHandlerException, KustvaktException {
+ public void testRetrieveOwnerPrivateVCInfo ()
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
JsonNode node = testSearchVC("dory", "dory", "dory VC");
assertEquals("dory VC", node.at("/name").asText());
@@ -199,14 +201,13 @@
assertEquals("published VC", node.at("/name").asText());
assertEquals(VirtualCorpusType.PUBLISHED.displayName(),
node.at("/type").asText());
-
+
// check gill in the hidden group of the vc
- ClientResponse response = resource().path(API_VERSION).path("group").path("list")
- .path("system-admin").queryParam("status", "HIDDEN")
- .header(Attributes.AUTHORIZATION,
- HttpAuthorizationHandler
- .createBasicAuthorizationHeaderValue(
- "admin", "pass"))
+ ClientResponse response = resource().path(API_VERSION).path("group")
+ .path("list").path("system-admin")
+ .queryParam("status", "HIDDEN")
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue("admin", "pass"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.get(ClientResponse.class);
@@ -241,17 +242,17 @@
}
@Test
- public void testListAvailableVCByOtherUser () throws UniformInterfaceException,
- ClientHandlerException, KustvaktException {
+ public void testListAvailableVCByOtherUser ()
+ throws UniformInterfaceException, ClientHandlerException,
+ KustvaktException {
ClientResponse response = resource().path(API_VERSION).path("vc")
- .path("dory")
- .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .path("dory").header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("pearl", "pass"))
.get(ClientResponse.class);
String entity = response.getEntity(String.class);
JsonNode node = JsonUtils.readTree(entity);
-
+
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
assertEquals(StatusCodes.AUTHORIZATION_FAILED,
node.at("/errors/0/0").asInt());
@@ -313,9 +314,9 @@
public void testCreatePublishedVC () throws KustvaktException {
String json = "{\"type\": \"PUBLISHED\""
+ ",\"corpusQuery\": \"corpusSigle=GOE\"}";
-
+
String vcName = "new published vc";
-
+
ClientResponse response = resource().path(API_VERSION).path("vc")
.path("VirtualCorpusControllerTest").path(vcName)
.header(Attributes.AUTHORIZATION,
@@ -334,8 +335,8 @@
assertEquals(vcName, node.get(0).get("name").asText());
// EM: check hidden access
- node = testlistAccessByGroup("admin","");
- node = node.get(node.size()-1);
+ node = testlistAccessByGroup("admin", "");
+ node = node.get(node.size() - 1);
assertEquals("system", node.at("/createdBy").asText());
assertEquals(vcName, node.at("/vcName").asText());
assertTrue(node.at("/userGroupName").asText().startsWith("auto"));
@@ -531,9 +532,9 @@
assertEquals("corpusQuery is null", node.at("/errors/0/1").asText());
assertEquals("corpusQuery", node.at("/errors/0/2").asText());
}
-
+
@Test
- public void testCreateVCWithoutEntity() throws KustvaktException {
+ public void testCreateVCWithoutEntity () throws KustvaktException {
ClientResponse response = resource().path(API_VERSION).path("vc")
.path("VirtualCorpusControllerTest").path("new vc")
.header(Attributes.AUTHORIZATION,
@@ -554,8 +555,7 @@
@Test
public void testCreateVCWithoutType () throws KustvaktException {
- String json = "{\"corpusQuery\": "
- + "\"creationDate since 1820\"}";
+ String json = "{\"corpusQuery\": " + "\"creationDate since 1820\"}";
ClientResponse response = resource().path(API_VERSION).path("vc")
.path("VirtualCorpusControllerTest").path("new vc")
@@ -601,7 +601,7 @@
+ "VirtualCorpusType` from String \"PRIVAT\": value not one of "
+ "declared Enum instance names"));
}
-
+
@Test
public void testDeleteVCUnauthorized () throws KustvaktException {
ClientResponse response = resource().path(API_VERSION).path("vc")
@@ -650,8 +650,8 @@
// 2nd edit
json = "{\"description\": \"test vc\"}";
- response = resource().path(API_VERSION).path("vc")
- .path("dory").path("dory VC")
+ response = resource().path(API_VERSION).path("vc").path("dory")
+ .path("dory VC")
.header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "pass"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
@@ -666,6 +666,29 @@
}
@Test
+ public void testEditCorpusQuery () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ String json = "{\"corpusQuery\": \"corpusSigle=WPD17\"}";
+
+ ClientResponse response = resource().path(API_VERSION).path("vc")
+ .path("dory").path("dory VC")
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue("dory", "pass"))
+ .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+ .put(ClientResponse.class, json);
+
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+ // check VC
+ JsonNode node = testListVC("dory");
+ String koralQuery = node.get(0).get("koralQuery").asText();
+ node = JsonUtils.readTree(koralQuery);
+ assertEquals("WPD17", node.at("/collection/value").asText());
+ assertTrue(koralQuery.contains("WPD17"));
+ }
+
+ @Test
public void testEditVCNotOwner () throws KustvaktException {
String json = "{\"description\": \"edited vc\"}";
@@ -694,13 +717,13 @@
@Test
public void testPublishProjectVC () throws KustvaktException {
- String vcName= "group VC";
-
+ String vcName = "group VC";
+
// check the vc type
JsonNode node = testSearchVC("dory", "dory", vcName);
assertEquals(VirtualCorpusType.PROJECT.displayName(),
node.get("type").asText());
-
+
// edit vc
String json = "{\"type\": \"PUBLISHED\"}";
ClientResponse response = resource().path(API_VERSION).path("vc")
@@ -721,7 +744,7 @@
// check hidden VC access
node = testlistAccessByGroup("admin", "");
assertEquals(4, node.size());
- node = node.get(node.size()-1);
+ node = node.get(node.size() - 1);
assertEquals(vcName, node.at("/vcName").asText());
assertEquals("system", node.at("/createdBy").asText());
assertTrue(node.at("/userGroupName").asText().startsWith("auto"));
@@ -729,8 +752,8 @@
// edit 2nd
json = "{\"type\": \"PROJECT\"}";
- response = resource().path(API_VERSION).path("vc")
- .path("dory").path("group VC")
+ response = resource().path(API_VERSION).path("vc").path("dory")
+ .path("group VC")
.header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "pass"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
@@ -757,29 +780,31 @@
node.at("/errors/0/1").asText());
}
-// @Test
-// public void testlistAccessMissingId () throws KustvaktException {
-// ClientResponse response = resource().path(API_VERSION).path("vc")
-// .path("access")
-// .header(Attributes.AUTHORIZATION,
-// HttpAuthorizationHandler
-// .createBasicAuthorizationHeaderValue(
-// "VirtualCorpusControllerTest", "pass"))
-// .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-// .get(ClientResponse.class);
-// String entity = response.getEntity(String.class);
-// JsonNode node = JsonUtils.readTree(entity);
-// assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-// assertEquals(StatusCodes.MISSING_PARAMETER,
-// node.at("/errors/0/0").asInt());
-// assertEquals("vcId", node.at("/errors/0/1").asText());
-// }
+ // @Test
+ // public void testlistAccessMissingId () throws KustvaktException
+ // {
+ // ClientResponse response =
+ // resource().path(API_VERSION).path("vc")
+ // .path("access")
+ // .header(Attributes.AUTHORIZATION,
+ // HttpAuthorizationHandler
+ // .createBasicAuthorizationHeaderValue(
+ // "VirtualCorpusControllerTest", "pass"))
+ // .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+ // .get(ClientResponse.class);
+ // String entity = response.getEntity(String.class);
+ // JsonNode node = JsonUtils.readTree(entity);
+ // assertEquals(Status.BAD_REQUEST.getStatusCode(),
+ // response.getStatus());
+ // assertEquals(StatusCodes.MISSING_PARAMETER,
+ // node.at("/errors/0/0").asInt());
+ // assertEquals("vcId", node.at("/errors/0/1").asText());
+ // }
@Test
public void testlistAccessByGroup () throws KustvaktException {
ClientResponse response = resource().path(API_VERSION).path("vc")
- .path("access")
- .queryParam("groupName", "dory group")
+ .path("access").queryParam("groupName", "dory group")
.header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "pass"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
@@ -791,7 +816,7 @@
assertEquals(2, node.at("/0/vcId").asInt());
assertEquals("group VC", node.at("/0/vcName").asText());
assertEquals(2, node.at("/0/userGroupId").asInt());
-
+
assertEquals("dory group", node.at("/0/userGroupName").asText());
}
@@ -801,19 +826,20 @@
String vcName = "marlin VC";
String groupName = "marlin group";
-
+
// check the vc type
JsonNode node = testSearchVC("marlin", "marlin", vcName);
assertEquals(vcName, node.at("/name").asText());
assertEquals("private", node.at("/type").asText());
-
- ClientResponse response = testShareVCByCreator("marlin", vcName, groupName);
+
+ ClientResponse response =
+ testShareVCByCreator("marlin", vcName, groupName);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
// check the vc type
node = testSearchVC("marlin", "marlin", vcName);
assertEquals("project", node.at("/type").asText());
-
+
// list vc access by marlin
node = testlistAccessByGroup("marlin", groupName);
assertEquals(2, node.size());
@@ -830,19 +856,19 @@
// delete access by vc-admin
// dory is a vc-admin in marlin group
- testDeleteAccess("dory", accessId);
+ response = testDeleteAccess("dory", accessId);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
// list vc access by dory
node = testlistAccessByGroup("dory", groupName);
assertEquals(1, node.size());
-
+
testEditVCType("marlin", "marlin", vcName, VirtualCorpusType.PRIVATE);
}
-
- private ClientResponse testShareVCByCreator (String vcCreator, String vcName, String groupName)
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ private ClientResponse testShareVCByCreator (String vcCreator,
+ String vcName, String groupName) throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
return resource().path(API_VERSION).path("vc").path(vcCreator)
.path(vcName).path("share").path(groupName)
@@ -852,29 +878,52 @@
.post(ClientResponse.class);
}
- private void testShareVCNonUniqueAccess (String vcCreator, String vcName, String groupName)
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
- ClientResponse response = testShareVCByCreator(vcCreator, vcName, groupName);
+ private void testShareVCNonUniqueAccess (String vcCreator, String vcName,
+ String groupName) throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ ClientResponse response =
+ testShareVCByCreator(vcCreator, vcName, groupName);
JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
assertEquals(StatusCodes.DB_INSERT_FAILED,
node.at("/errors/0/0").asInt());
-
+
// EM: message differs depending on the database used
// for testing. The message below is from sqlite.
-// assertTrue(node.at("/errors/0/1").asText()
-// .startsWith("[SQLITE_CONSTRAINT_UNIQUE]"));
+ // assertTrue(node.at("/errors/0/1").asText()
+ // .startsWith("[SQLITE_CONSTRAINT_UNIQUE]"));
}
@Test
- public void testShareVCByVCAAdmin ()
- throws UniformInterfaceException, ClientHandlerException,
- KustvaktException {
+ public void testShareUnknownVC () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ ClientResponse response = testShareVCByCreator("marlin",
+ "non-existing-vc", "marlin group");
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
+ assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+ node.at("/errors/0/0").asInt());
+ }
+
+ @Test
+ public void testShareUnknownGroup () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ ClientResponse response = testShareVCByCreator("marlin", "marlin VC",
+ "non-existing-group");
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
+ assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+ node.at("/errors/0/0").asInt());
+ }
+
+ @Test
+ public void testShareVCByVCAAdmin () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
// dory is VCA in marlin group
ClientResponse response = resource().path(API_VERSION).path("vc")
- .path("marlin").path("marlin VC").path("share").path("marlin group")
+ .path("marlin").path("marlin VC").path("share")
+ .path("marlin group")
.header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "pass"))
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
@@ -910,7 +959,7 @@
node.at("/errors/0/1").asText());
}
- private void testDeleteAccess (String username, String accessId)
+ private ClientResponse testDeleteAccess (String username, String accessId)
throws UniformInterfaceException, ClientHandlerException,
KustvaktException {
ClientResponse response = resource().path(API_VERSION).path("vc")
@@ -920,7 +969,7 @@
.header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
.delete(ClientResponse.class);
- assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ return response;
}
private void testDeleteAccessUnauthorized (String accessId)
@@ -945,4 +994,14 @@
"Unauthorized operation for user: VirtualCorpusControllerTest",
node.at("/errors/0/1").asText());
}
+
+ @Test
+ public void testDeleteNonExistingAccess () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+ ClientResponse response = testDeleteAccess("dory", "100");
+ assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+ JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+ assertEquals(StatusCodes.NO_RESOURCE_FOUND, node.at("/errors/0/0").asInt());
+ }
}