Update auto-hidden group mechanism.

Change-Id: I4794f7bf75fc102367fbba39941194267e05276e
diff --git a/src/main/java/de/ids_mannheim/korap/dao/QueryAccessDao.java b/src/main/java/de/ids_mannheim/korap/dao/QueryAccessDao.java
index 1d5ce75..10bf684 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/QueryAccessDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/QueryAccessDao.java
@@ -243,6 +243,7 @@
         }
     }
 
+    @Deprecated
     public void createAccessToQuery (QueryDO query, UserGroup userGroup)
             throws KustvaktException {
     
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 42d2021..72fdb69 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
@@ -8,6 +8,7 @@
 import org.springframework.transaction.annotation.Transactional;
 
 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.Role;
 import de.ids_mannheim.korap.entity.Role_;
@@ -190,4 +191,22 @@
         
     }
 
+    public Role retrieveRoleByPrivilegeAndQuery (PrivilegeType p,
+            int queryId) throws KustvaktException {
+
+        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+        CriteriaQuery<Role> query = cb.createQuery(Role.class);
+
+        Root<Role> role = query.from(Role.class);
+        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));
+
+        TypedQuery<Role> q = entityManager.createQuery(query);
+        return (Role) q.getSingleResult();
+    }
+
 }
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 afd6086..a79e13f 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -5,6 +5,27 @@
 import java.util.List;
 import java.util.Set;
 
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
+import de.ids_mannheim.korap.constant.PredefinedRole;
+import de.ids_mannheim.korap.constant.PrivilegeType;
+import de.ids_mannheim.korap.constant.QueryAccessStatus;
+import de.ids_mannheim.korap.constant.UserGroupStatus;
+import de.ids_mannheim.korap.entity.QueryAccess;
+import de.ids_mannheim.korap.entity.QueryAccess_;
+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_;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.ParameterChecker;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.NoResultException;
 import jakarta.persistence.PersistenceContext;
@@ -16,28 +37,6 @@
 import jakarta.persistence.criteria.Predicate;
 import jakarta.persistence.criteria.Root;
 
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-import de.ids_mannheim.korap.constant.GroupMemberStatus;
-import de.ids_mannheim.korap.constant.PredefinedRole;
-import de.ids_mannheim.korap.constant.PrivilegeType;
-import de.ids_mannheim.korap.constant.UserGroupStatus;
-import de.ids_mannheim.korap.constant.QueryAccessStatus;
-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_;
-import de.ids_mannheim.korap.entity.QueryDO;
-import de.ids_mannheim.korap.entity.QueryAccess;
-import de.ids_mannheim.korap.entity.QueryAccess_;
-import de.ids_mannheim.korap.entity.QueryDO_;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.utils.ParameterChecker;
-
 /**
  * Manages database queries and transactions regarding
  * {@link UserGroup} entity and database table.
@@ -69,20 +68,22 @@
         entityManager.persist(group);
         entityManager.flush();
         
-        Set<Role> roles = createUserGroupAdminRoles(group);
-        for (Role role : roles) {
-            entityManager.persist(role);
-        }
-        entityManager.flush();
+        if (createdBy != "system") {
+            Set<Role> roles = createUserGroupAdminRoles(group);
+            for (Role role : roles) {
+                entityManager.persist(role);
+            }
+            entityManager.flush();
         
-        UserGroupMember owner = new UserGroupMember();
-        owner.setUserId(createdBy);
-        owner.setCreatedBy(createdBy);
-        owner.setStatus(GroupMemberStatus.ACTIVE);
-        owner.setGroup(group);
-        owner.setRoles(roles);
-        entityManager.persist(owner);
-        entityManager.flush();
+            UserGroupMember owner = new UserGroupMember();
+            owner.setUserId(createdBy);
+            owner.setCreatedBy(createdBy);
+            owner.setStatus(GroupMemberStatus.ACTIVE);
+            owner.setGroup(group);
+            owner.setRoles(roles);
+            entityManager.persist(owner);
+            entityManager.flush();
+        };
         
         return group.getId();
     }
@@ -249,23 +250,24 @@
                     "Group " + groupName + " is not found", groupName, e);
         }
     }
-
-    public UserGroup retrieveHiddenGroupByQuery (int queryId)
+    
+    public UserGroup retrieveHiddenGroupByQueryName (String queryName)
             throws KustvaktException {
-        ParameterChecker.checkIntegerValue(queryId, "queryId");
+        ParameterChecker.checkNameValue(queryName, "queryName");
 
         CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
         CriteriaQuery<UserGroup> criteriaQuery = criteriaBuilder
                 .createQuery(UserGroup.class);
 
         Root<UserGroup> root = criteriaQuery.from(UserGroup.class);
-        Join<UserGroup, QueryAccess> access = root.join(UserGroup_.queryAccess);
-        Join<QueryAccess, QueryDO> query = access.join(QueryAccess_.query);
+        Join<UserGroup, Role> group_role = root.join(UserGroup_.roles);
+        Join<Role, QueryDO> query_role = group_role.join(Role_.query);
 
         Predicate p = criteriaBuilder.and(
                 criteriaBuilder.equal(root.get(UserGroup_.status),
                         UserGroupStatus.HIDDEN),
-                criteriaBuilder.equal(query.get(QueryDO_.id), queryId));
+                criteriaBuilder.equal(query_role.get(QueryDO_.name), queryName)
+        );
 
         criteriaQuery.select(root);
         criteriaQuery.where(p);
@@ -275,7 +277,40 @@
             return (UserGroup) q.getSingleResult();
         }
         catch (NoResultException e) {
-            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND,
+            throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
+                    "No hidden group for query " + queryName
+                            + " is found",
+                    String.valueOf(queryName), e);
+        }
+
+    }
+
+    public UserGroup retrieveHiddenGroupByQueryId (int queryId)
+            throws KustvaktException {
+        ParameterChecker.checkIntegerValue(queryId, "queryId");
+
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<UserGroup> criteriaQuery = criteriaBuilder
+                .createQuery(UserGroup.class);
+
+        Root<UserGroup> root = criteriaQuery.from(UserGroup.class);
+        Join<UserGroup, Role> group_role = root.join(UserGroup_.roles);
+        Join<Role, QueryDO> query_role = group_role.join(Role_.query);
+
+        Predicate p = criteriaBuilder.and(
+                criteriaBuilder.equal(root.get(UserGroup_.status),
+                        UserGroupStatus.HIDDEN),
+                criteriaBuilder.equal(query_role.get(QueryDO_.id), queryId));
+
+        criteriaQuery.select(root);
+        criteriaQuery.where(p);
+        Query q = entityManager.createQuery(criteriaQuery);
+
+        try {
+            return (UserGroup) q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
                     "No hidden group for query with id " + queryId
                             + " is found",
                     String.valueOf(queryId), e);
diff --git a/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java b/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
index 1bf7fb9..d7b57bd 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
@@ -45,6 +45,7 @@
     public void addMember (UserGroupMember member) throws KustvaktException {
         ParameterChecker.checkObjectValue(member, "userGroupMember");
         entityManager.persist(member);
+        entityManager.flush();
     }
 
     public void updateMember (UserGroupMember member) throws KustvaktException {
diff --git a/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java b/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
index c43ddc4..bc09718 100644
--- a/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
+++ b/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
@@ -30,6 +30,8 @@
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private List<UserGroupMemberDto> members;
 
+    @JsonInclude(JsonInclude.Include.NON_NULL)
     private GroupMemberStatus userMemberStatus;
+    @JsonInclude(JsonInclude.Include.NON_NULL)
     private List<PredefinedRole> userRoles;
 }
diff --git a/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java b/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
index 4508165..4bb17fe 100644
--- a/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
+++ b/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
@@ -57,8 +57,9 @@
             cascade = CascadeType.REMOVE)
     private List<UserGroupMember> members;
 
-    @OneToMany(mappedBy = "userGroup", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
-    private List<QueryAccess> queryAccess;
+    @OneToMany(mappedBy = "userGroup", fetch = FetchType.LAZY, 
+            cascade = CascadeType.REMOVE)
+    private List<Role> roles;
 
     @Override
     public String toString () {
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 212da68..3a9483f 100644
--- a/src/main/java/de/ids_mannheim/korap/service/QueryService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
@@ -3,6 +3,7 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -27,6 +28,7 @@
 import de.ids_mannheim.korap.dao.QueryAccessDao;
 import de.ids_mannheim.korap.dao.QueryDao;
 import de.ids_mannheim.korap.dao.RoleDao;
+import de.ids_mannheim.korap.dao.UserGroupDao;
 import de.ids_mannheim.korap.dao.UserGroupMemberDao;
 import de.ids_mannheim.korap.dto.QueryAccessDto;
 import de.ids_mannheim.korap.dto.QueryDto;
@@ -48,6 +50,7 @@
 import de.ids_mannheim.korap.web.controller.QueryReferenceController;
 import de.ids_mannheim.korap.web.controller.VirtualCorpusController;
 import de.ids_mannheim.korap.web.input.QueryJson;
+import jakarta.persistence.NoResultException;
 import jakarta.ws.rs.core.Response.Status;
 
 /**
@@ -81,6 +84,8 @@
     @Autowired
     private RoleDao roleDao;
     @Autowired
+    private UserGroupDao userGroupDao;
+    @Autowired
     private UserGroupMemberDao memberDao;
 
     @Autowired
@@ -155,7 +160,7 @@
         return dtos;
     }
 
-    public void deleteQueryByName (String username, String queryName,
+    public void deleteQueryByName (String deletedBy, String queryName,
             String createdBy, QueryType type) throws KustvaktException {
 
         QueryDO query = queryDao.retrieveQueryByName(queryName, createdBy);
@@ -165,15 +170,13 @@
             throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
                     "Query " + code + " is not found.", String.valueOf(code));
         }
-        else if (query.getCreatedBy().equals(username)
-                || adminDao.isAdmin(username)) {
+        else if (query.getCreatedBy().equals(deletedBy)
+                || adminDao.isAdmin(deletedBy)) {
 
             if (query.getType().equals(ResourceType.PUBLISHED)) {
-                QueryAccess access = accessDao
-                        .retrieveHiddenAccess(query.getId());
-                accessDao.deleteAccess(access, "system");
-                userGroupService.deleteAutoHiddenGroup(
-                        access.getUserGroup().getId(), "system");
+                UserGroup group = userGroupDao
+                        .retrieveHiddenGroupByQueryName(queryName);
+                userGroupDao.deleteGroup(group.getId(), deletedBy, false);
             }
             if (type.equals(QueryType.VIRTUAL_CORPUS)
                     && VirtualCorpusCache.contains(queryName)) {
@@ -183,7 +186,7 @@
         }
         else {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
-                    "Unauthorized operation for user: " + username, username);
+                    "Unauthorized operation for user: " + deletedBy, deletedBy);
         }
     }
 
@@ -232,11 +235,10 @@
             if (existingQuery.getType().equals(ResourceType.PUBLISHED)) {
                 // withdraw from publication
                 if (!type.equals(ResourceType.PUBLISHED)) {
-                    QueryAccess hiddenAccess = accessDao
-                            .retrieveHiddenAccess(existingQuery.getId());
-                    deleteQueryAccess(hiddenAccess.getId(), "system");
-                    int groupId = hiddenAccess.getUserGroup().getId();
-                    userGroupService.deleteAutoHiddenGroup(groupId, "system");
+                    UserGroup group = userGroupDao
+                            .retrieveHiddenGroupByQueryName(queryName);
+                    int groupId = group.getId();
+                    userGroupDao.deleteGroup(groupId, username, false);
                     // EM: should the users within the hidden group
                     // receive
                     // notifications?
@@ -256,22 +258,22 @@
 
     private void publishQuery (int queryId) throws KustvaktException {
 
-        QueryAccess access = accessDao.retrieveHiddenAccess(queryId);
+//        QueryAccess access = accessDao.retrieveHiddenAccess(queryId);
         // check if hidden access exists
-        if (access == null) {
+//        if (access == null) {
             QueryDO query = queryDao.retrieveQueryById(queryId);
             // create and assign a new hidden group
             int groupId = userGroupService.createAutoHiddenGroup();
             UserGroup autoHidden = userGroupService
                     .retrieveUserGroupById(groupId);
-            accessDao.createAccessToQuery(query, autoHidden);
-//                    , "system", QueryAccessStatus.HIDDEN);
-        }
-        else {
-            // should not happened
-            jlog.error("Cannot publish query with id: " + queryId
-                    + ". Hidden access exists! Access id: " + access.getId());
-        }
+//            accessDao.createAccessToQuery(query, autoHidden);
+            addRoleToQuery(query, autoHidden);
+//        }
+//        else {
+//            // should not happened
+//            jlog.error("Cannot publish query with id: " + queryId
+//                    + ". Hidden access exists! Access id: " + access.getId());
+//        }
     }
 
     public void storeQuery (QueryJson query, String queryName,
@@ -493,7 +495,7 @@
         }
         else {
             try {
-                createAccessToQuery(query, userGroup);
+                addRoleToQuery(query, userGroup);
             }
             catch (Exception e) {
                 Throwable cause = e;
@@ -514,7 +516,7 @@
         }
     }
     
-    public void createAccessToQuery (QueryDO query, UserGroup userGroup)
+    public void addRoleToQuery (QueryDO query, UserGroup userGroup)
             throws KustvaktException {
     
         List<UserGroupMember> members = memberDao
@@ -577,18 +579,18 @@
         UserGroup userGroup = userGroupService
                 .retrieveUserGroupByName(groupName);
 
-        Set<Role> accessList;
+        Set<Role> roles;
         if (adminDao.isAdmin(username)
                 || userGroupService.isUserGroupAdmin(username, userGroup)) {
             //            accessList = accessDao.retrieveAllAccessByGroup(userGroup.getId());
-            accessList = roleDao.retrieveRoleByGroupId(userGroup.getId(), true);
+            roles = roleDao.retrieveRoleByGroupId(userGroup.getId(), true);
 
         }
         else {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
-        return accessConverter.createRoleDto(accessList);
+        return accessConverter.createRoleDto(roles);
     }
 
     public void deleteQueryAccess (int roleId, String username)
@@ -699,12 +701,28 @@
                     && !username.equals("guest")) {
                 // add user in the query's auto group
                 UserGroup userGroup = userGroupService
-                        .retrieveHiddenUserGroupByQuery(query.getId());
+                        .retrieveHiddenUserGroupByQueryId(query.getId());
                 try {
+                    
+                    Role r1= roleDao.retrieveRoleByPrivilegeAndQuery(
+                            PrivilegeType.READ_QUERY, query.getId());
+                    Set<Role> memberRoles = new HashSet<Role>();
+                    memberRoles.add(r1);
+                    
                     userGroupService.addGroupMember(username, userGroup,
-                            "system", GroupMemberStatus.ACTIVE);
+                            "system", GroupMemberStatus.ACTIVE, memberRoles);    
                     // member roles are not set (not necessary)
                 }
+                catch (NoResultException ne) {
+                    Role r1 = new Role(PredefinedRole.QUERY_ACCESS,
+                            PrivilegeType.READ_QUERY, userGroup);
+                    roleDao.addRole(r1);
+                    Set<Role> memberRoles = new HashSet<Role>();
+                    memberRoles.add(r1);
+                    
+                    userGroupService.addGroupMember(username, userGroup,
+                            "system", GroupMemberStatus.ACTIVE, memberRoles);                
+                }
                 catch (KustvaktException e) {
                     // member exists
                     // skip adding user to hidden group
diff --git a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
index 1bd6e74..4bf3bff 100644
--- a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -137,9 +137,18 @@
         return userGroupDao.retrieveGroupByName(groupName, false);
     }
 
-    public UserGroup retrieveHiddenUserGroupByQuery (int queryId)
+    public UserGroup retrieveHiddenUserGroupByQueryId (int queryId)
             throws KustvaktException {
-        return userGroupDao.retrieveHiddenGroupByQuery(queryId);
+        return userGroupDao.retrieveHiddenGroupByQueryId(queryId);
+    }
+    
+    public UserGroupDto retrieveHiddenUserGroupByQueryName (String queryName)
+            throws KustvaktException {
+        UserGroup group = userGroupDao
+                .retrieveHiddenGroupByQueryName(queryName);
+        List<UserGroupMember> members = groupMemberDao
+                .retrieveMemberByGroupId(group.getId());
+        return converter.createUserGroupDto(group, members, null, null);
     }
 
     public List<UserGroupDto> retrieveUserGroupByStatus (String username,
@@ -160,7 +169,7 @@
         }
         return dtos;
     }
-
+    
     public List<UserGroupMember> retrieveQueryAccessAdmins (UserGroup userGroup)
             throws KustvaktException {
         List<UserGroupMember> groupAdmins = groupMemberDao.retrieveMemberByRole(
@@ -222,7 +231,7 @@
         UserGroup userGroup = null;
         boolean groupExists = false;
         try {
-            userGroup = userGroupDao.retrieveGroupByName(groupName, false);
+            userGroup = retrieveUserGroupByName(groupName);
             groupExists = true;
         }
         catch (KustvaktException e) {
@@ -235,7 +244,7 @@
             try {
                 userGroupDao.createGroup(groupName, description, createdBy,
                         UserGroupStatus.ACTIVE);
-                userGroup = userGroupDao.retrieveGroupByName(groupName, false);
+                userGroup = retrieveUserGroupByName(groupName);
             }
             // handle DB exceptions, e.g. unique constraint
             catch (Exception e) {
@@ -261,8 +270,7 @@
 
     public void deleteGroup (String groupName, String username)
             throws KustvaktException {
-        UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName,
-                false);
+        UserGroup userGroup = retrieveUserGroupByName(groupName);
         if (userGroup.getStatus() == UserGroupStatus.DELETED) {
             // EM: should this be "not found" instead?
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
@@ -290,13 +298,6 @@
         return groupId;
     }
 
-    public void deleteAutoHiddenGroup (int groupId, String deletedBy)
-            throws KustvaktException {
-        // default hard delete
-        userGroupDao.deleteGroup(groupId, deletedBy,
-                config.isSoftDeleteAutoGroup());
-    }
-
     /**
      * Adds a user to the specified usergroup. If the username with
      * {@link GroupMemberStatus} DELETED exists as a member of the
@@ -336,6 +337,12 @@
     public void addGroupMember (String username, UserGroup userGroup,
             String createdBy, GroupMemberStatus status)
             throws KustvaktException {
+        addGroupMember(username, userGroup, createdBy, status, null);
+    }
+    
+    public void addGroupMember (String username, UserGroup userGroup,
+            String createdBy, GroupMemberStatus status, Set<Role> roles)
+            throws KustvaktException {
         int groupId = userGroup.getId();
         ParameterChecker.checkIntegerValue(groupId, "userGroupId");
 
@@ -354,6 +361,9 @@
         member.setGroup(userGroup);
         member.setStatus(status);
         member.setUserId(username);
+        if (roles !=null) {
+            member.setRoles(roles);
+        }
         groupMemberDao.addMember(member);
     }
 
@@ -450,8 +460,7 @@
         ParameterChecker.checkStringValue(username, "userId");
         ParameterChecker.checkStringValue(groupName, "groupName");
 
-        UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName,
-                false);
+        UserGroup userGroup = retrieveUserGroupByName(groupName);
         if (userGroup.getStatus() == UserGroupStatus.DELETED) {
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
                     "Group " + userGroup.getName() + " has been deleted.",
@@ -513,8 +522,7 @@
     public void deleteGroupMember (String memberId, String groupName,
             String deletedBy) throws KustvaktException {
 
-        UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName,
-                false);
+        UserGroup userGroup = retrieveUserGroupByName(groupName);
         if (userGroup.getStatus() == UserGroupStatus.DELETED) {
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
                     "Group " + userGroup.getName() + " has been deleted.",
diff --git a/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupAdminController.java b/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupAdminController.java
index 4ed6266..6af97be 100644
--- a/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupAdminController.java
+++ b/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupAdminController.java
@@ -59,6 +59,21 @@
             throw kustvaktResponseHandler.throwit(e);
         }
     }
+    
+    @POST
+    @Path("hidden")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    public UserGroupDto getHiddenUserGroupForQuery (
+            @FormParam("queryName") String queryName) {
+        try {
+            return service.retrieveHiddenUserGroupByQueryName(queryName);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+    
+    
 
     /**
      * Retrieves a specific user-group. Only system admins are
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 6c91dd6..d7f937c 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
@@ -360,7 +360,7 @@
      */
     @DELETE
     @Path("access/{accessId}")
-    public Response deleteVCAccessById (
+    public Response deleteAccessById (
             @Context SecurityContext securityContext,
             @PathParam("accessId") int accessId) {
         TokenContext context = (TokenContext) securityContext
@@ -386,7 +386,7 @@
      */
     @GET
     @Path("access")
-    public List<QueryAccessDto> listVCAccesses (
+    public List<QueryAccessDto> listAccess (
             @Context SecurityContext securityContext,
             @QueryParam("groupName") String groupName) {
         TokenContext context = (TokenContext) securityContext