Add web-service: delete role by query and group.
Change-Id: I3227b1162c44b755cf07c13373bbfe1eeb88d58e
diff --git a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
index 4fcba47..8ec7c89 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
@@ -9,9 +9,11 @@
import de.ids_mannheim.korap.constant.PredefinedRole;
import de.ids_mannheim.korap.constant.PrivilegeType;
+import de.ids_mannheim.korap.entity.QueryDO;
import de.ids_mannheim.korap.entity.QueryDO_;
import de.ids_mannheim.korap.entity.Role;
import de.ids_mannheim.korap.entity.Role_;
+import de.ids_mannheim.korap.entity.UserGroup;
import de.ids_mannheim.korap.entity.UserGroupMember;
import de.ids_mannheim.korap.entity.UserGroupMember_;
import de.ids_mannheim.korap.entity.UserGroup_;
@@ -30,6 +32,7 @@
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.ListJoin;
import jakarta.persistence.criteria.Root;
+import jakarta.persistence.criteria.Subquery;
/**
* Manages database queries and transactions regarding {@link Role}
@@ -162,25 +165,6 @@
return new HashSet<Role>(resultList);
}
- public void deleteRole (int roleId) throws KustvaktException {
-
- CriteriaBuilder cb = entityManager.getCriteriaBuilder();
- CriteriaDelete<Role> delete = cb.createCriteriaDelete(Role.class);
- Root<Role> role = delete.from(Role.class);
-
- delete.where(
- cb.equal(role.get("id"), roleId));
-
- try {
- entityManager.createQuery(delete).executeUpdate();
- }
- catch (NoResultException e) {
- throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
- "Role is not found", String.valueOf(roleId));
- }
-
- }
-
public Role retrieveRoleByGroupIdQueryIdPrivilege (int groupId, int queryId,
PrivilegeType p) throws KustvaktException {
@@ -192,12 +176,51 @@
role.fetch(Role_.query, JoinType.INNER);
query.select(role);
- query.where(cb.equal(role.get(Role_.query).get(QueryDO_.id), queryId),
- cb.equal(role.get(Role_.privilege), p), cb.equal(
- role.get(Role_.userGroup).get(UserGroup_.id), groupId));
+ query.where(
+ cb.equal(role.get(Role_.query).get(QueryDO_.id), queryId),
+ cb.equal(role.get(Role_.privilege), p),
+ cb.equal(role.get(Role_.userGroup).get(UserGroup_.id),
+ groupId));
TypedQuery<Role> q = entityManager.createQuery(query);
return (Role) q.getSingleResult();
}
+ @Deprecated
+ public void deleteRole (int roleId) throws KustvaktException {
+
+ CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+ CriteriaDelete<Role> delete = cb.createCriteriaDelete(Role.class);
+ Root<Role> role = delete.from(Role.class);
+
+ delete.where(
+ cb.equal(role.get("id"), roleId));
+
+ entityManager.createQuery(delete).executeUpdate();
+ }
+
+ public void deleteRoleByGroupAndQuery (String groupName,
+ String queryCreator, String queryName) throws KustvaktException {
+ CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+
+ CriteriaDelete<Role> delete = cb.createCriteriaDelete(Role.class);
+ Root<Role> deleteRole = delete.from(Role.class);
+
+ Subquery<Integer> subquery = delete.subquery(Integer.class);
+ Root<Role> role = subquery.from(Role.class);
+ Join<Role, UserGroup> groupRole = role.join(Role_.userGroup);
+ Join<Role, QueryDO> queryRole = role.join(Role_.query);
+
+ subquery.select(role.get(Role_.id))
+ .where(cb.and(
+ cb.equal(groupRole.get(UserGroup_.name), groupName),
+ cb.equal(queryRole.get(QueryDO_.createdBy),
+ queryCreator),
+ cb.equal(queryRole.get(QueryDO_.name), queryName)));
+
+
+ delete.where(deleteRole.get(Role_.id).in(subquery));
+ entityManager.createQuery(delete).executeUpdate();
+ }
+
}
diff --git a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
index 85b35e8..f8b0474 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -374,30 +374,4 @@
}
}
-
- public void deleteQueryFromGroup (int queryId, int groupId)
- throws KustvaktException {
- ParameterChecker.checkIntegerValue(queryId, "queryId");
- ParameterChecker.checkIntegerValue(groupId, "groupId");
-
- CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
- CriteriaQuery<QueryAccess> criteriaQuery = criteriaBuilder
- .createQuery(QueryAccess.class);
-
- Root<QueryAccess> root = criteriaQuery.from(QueryAccess.class);
- Join<QueryAccess, QueryDO> queryAccess = root.join(QueryAccess_.query);
- Join<QueryAccess, UserGroup> group = root.join(QueryAccess_.userGroup);
-
- Predicate query = criteriaBuilder.equal(queryAccess.get(QueryDO_.id),
- queryId);
- Predicate userGroup = criteriaBuilder.equal(group.get(UserGroup_.id),
- groupId);
-
- criteriaQuery.select(root);
- criteriaQuery.where(criteriaBuilder.and(query, userGroup));
- Query q = entityManager.createQuery(criteriaQuery);
- QueryAccess access = (QueryAccess) q.getSingleResult();
- entityManager.remove(access);
- }
-
}
diff --git a/src/main/java/de/ids_mannheim/korap/service/QueryService.java b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
index eba6a28..42fd7cb 100644
--- a/src/main/java/de/ids_mannheim/korap/service/QueryService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
@@ -581,7 +581,7 @@
return accessConverter.createQueryAccessDto(accessList);
}
- public List<QueryAccessDto> listQueryAccessByGroup (String username,
+ public List<QueryAccessDto> listRolesByGroup (String username,
String groupName) throws KustvaktException {
UserGroup userGroup = userGroupService
.retrieveUserGroupByName(groupName);
@@ -600,7 +600,8 @@
return accessConverter.createRoleDto(roles);
}
- public void deleteQueryAccess (int roleId, String username)
+ @Deprecated
+ public void deleteRoleById (int roleId, String username)
throws KustvaktException {
Role role = roleDao.retrieveRoleById(roleId);
@@ -615,6 +616,23 @@
}
}
+
+ public void deleteRoleByGroupAndQuery (String groupName,
+ String queryCreator, String queryName, String deleteBy)
+ throws KustvaktException {
+ UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName,
+ false);
+ if (userGroupService.isUserGroupAdmin(deleteBy, userGroup)
+ || adminDao.isAdmin(deleteBy)) {
+ roleDao.deleteRoleByGroupAndQuery(groupName, queryCreator,
+ queryName);
+ }
+ else {
+ throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+ "Unauthorized operation for user: " + deleteBy, deleteBy);
+ }
+
+ }
public JsonNode retrieveKoralQuery (String username, String queryName,
String createdBy, QueryType queryType) throws KustvaktException {
diff --git a/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index d7f937c..9ba7efa 100644
--- a/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -346,6 +346,36 @@
}
return Response.ok("SUCCESS").build();
}
+
+ /**
+ * Delete all roles for a given group name and vc. Only Group and
+ * system admin are eligible.
+ *
+ * @param securityContext
+ * @param vcCreator
+ * @param vcName
+ * @param groupName
+ * @return HTTP status 200, if successful
+ */
+ @DELETE
+ @Path("~{vcCreator}/{vcName}/delete/@{groupName}")
+ public Response deleteRoleByGroupAndQuery (
+ @Context SecurityContext securityContext,
+ @PathParam("vcCreator") String vcCreator,
+ @PathParam("vcName") String vcName,
+ @PathParam("groupName") String groupName) {
+ TokenContext context = (TokenContext) securityContext
+ .getUserPrincipal();
+ try {
+ scopeService.verifyScope(context, OAuth2Scope.DELETE_VC_ACCESS);
+ service.deleteRoleByGroupAndQuery(groupName, vcCreator, vcName,
+ context.getUsername());
+ }
+ catch (KustvaktException e) {
+ throw kustvaktResponseHandler.throwit(e);
+ }
+ return Response.ok().build();
+ }
/**
* Only VCA Admins and system admins are allowed to delete a
@@ -358,6 +388,7 @@
* @param accessId
* @return
*/
+ @Deprecated
@DELETE
@Path("access/{accessId}")
public Response deleteAccessById (
@@ -367,13 +398,16 @@
.getUserPrincipal();
try {
scopeService.verifyScope(context, OAuth2Scope.DELETE_VC_ACCESS);
- service.deleteQueryAccess(accessId, context.getUsername());
+ service.deleteRoleById(accessId, context.getUsername());
}
catch (KustvaktException e) {
throw kustvaktResponseHandler.throwit(e);
}
return Response.ok().build();
}
+
+
+
/**
* Lists active VC-accesses available to user.
@@ -386,7 +420,7 @@
*/
@GET
@Path("access")
- public List<QueryAccessDto> listAccess (
+ public List<QueryAccessDto> listRoles (
@Context SecurityContext securityContext,
@QueryParam("groupName") String groupName) {
TokenContext context = (TokenContext) securityContext
@@ -394,7 +428,7 @@
try {
scopeService.verifyScope(context, OAuth2Scope.VC_ACCESS_INFO);
if (groupName != null && !groupName.isEmpty()) {
- return service.listQueryAccessByGroup(context.getUsername(),
+ return service.listRolesByGroup(context.getUsername(),
groupName);
}
else {
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
index c4a43f7..442afdc 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
@@ -60,7 +60,7 @@
}
@Test
- public void testSharePrivateVCByGroupAdmin ()
+ public void testShareVC_ByGroupAdmin ()
throws ProcessingException, KustvaktException {
createMarlinGroup();
inviteMember(marlinGroupName, "marlin", "nemo");
@@ -69,11 +69,11 @@
JsonNode node = listAccessByGroup("marlin", marlinGroupName);
assertEquals(0, node.size());
+ // share by member unauthorized
Response response = shareVCByCreator("nemo", "nemo-vc",
marlinGroupName);
testResponseUnauthorized(response, "nemo");
-
Form form = new Form();
form.param("memberUsername", "nemo");
form.param("role", PredefinedRole.GROUP_ADMIN.name());
@@ -83,11 +83,42 @@
node = listAccessByGroup("marlin", marlinGroupName);
assertEquals(1, node.size());
-// System.out.println(node.toPrettyString());
deleteGroupByName(marlinGroupName, "marlin");
}
@Test
+ public void testSharePrivateVC () throws KustvaktException {
+ String vcName = "new_private_vc";
+ createPrivateVC(testUser, vcName);
+
+ String groupName = "DNB-group";
+ Response response = createUserGroup(groupName, "DNB users", testUser);
+ assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+ listUserGroup(testUser, groupName);
+ String memberName = "darla";
+ testInviteMember(groupName, testUser, memberName);
+ subscribeToGroup(memberName, groupName);
+
+ JsonNode node = listAccessByGroup(testUser, groupName);
+ assertEquals(0, node.size());
+
+ // share vc to group
+ shareVCByCreator(testUser, vcName, groupName);
+
+ // check member roles
+ node = listAccessByGroup(testUser, groupName);
+ assertEquals(1, node.size());
+
+ deleteRoleByGroupAndQuery(testUser, vcName, groupName, testUser);
+
+ node = listAccessByGroup(testUser, groupName);
+ assertEquals(0, node.size());
+
+ deleteVC(vcName, testUser, testUser);
+ deleteGroupByName(groupName, testUser);
+ }
+
+ @Test
public void testShareProjectVC () throws KustvaktException {
String vcName = "new_project_vc";
createProjectVC(testUser, vcName);
@@ -111,7 +142,7 @@
response = createUserGroup(groupName, "Owid users", testUser);
assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
listUserGroup(testUser, groupName);
- testInviteMember(groupName, testUser, "darla");
+ testInviteMember(groupName, testUser, memberName);
subscribeToGroup(memberName, groupName);
checkMemberInGroup(memberName, testUser, groupName);
@@ -138,6 +169,50 @@
node = JsonUtils.readTree(response.readEntity(String.class));
assertEquals(StatusCodes.NO_RESOURCE_FOUND,
node.at("/errors/0/0").asInt());
+
+ deleteGroupByName(groupName, testUser);
+ }
+
+ @Test
+ public void testShareMultipleVC () throws KustvaktException {
+ String vc1 = "new_private_vc";
+ String vc2 = "new_project_vc";
+ createPrivateVC(testUser, vc1);
+ createProjectVC(testUser, vc2);
+
+ String groupName = "DNB-group";
+ Response response = createUserGroup(groupName, "DNB users", testUser);
+ assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+ listUserGroup(testUser, groupName);
+ String memberName = "darla";
+ testInviteMember(groupName, testUser, memberName);
+ subscribeToGroup(memberName, groupName);
+
+ shareVC(testUser, vc1, groupName, testUser);
+ shareVC(testUser, vc2, groupName, testUser);
+
+ // list user VC
+ JsonNode node = listVC(testUser);
+ assertEquals(3, node.size());
+
+ node = listVC(memberName);
+ assertEquals(3, node.size());
+
+ deleteRoleByGroupAndQuery(testUser, vc1, groupName, testUser);
+
+ node = listVC(memberName);
+ assertEquals(2, node.size());
+
+ node = listVC(testUser);
+ assertEquals(3, node.size());
+
+ deleteVC(vc1, testUser, testUser);
+ deleteVC(vc2, testUser, testUser);
+
+ node = listVC(testUser);
+ assertEquals(1, node.size());
+
+ deleteGroupByName(groupName, testUser);
}
private JsonNode listUserGroup (String username, String groupName)
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
index 6972e16..cacca06 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
@@ -246,6 +246,18 @@
return response;
}
+ protected Response deleteRoleByGroupAndQuery (String vcCreator, String vcName,
+ String groupName, String deleteBy)
+ throws ProcessingException, KustvaktException {
+ Response response = target().path(API_VERSION).path("vc")
+ .path("~" + vcCreator).path(vcName).path("delete")
+ .path("@" + groupName).request()
+ .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+ .createBasicAuthorizationHeaderValue(deleteBy, "pass"))
+ .delete();
+ return response;
+ }
+
protected Response searchWithVCRef (String username, String vcCreator,
String vcName) throws KustvaktException {
Response response = target().path(API_VERSION).path("search")