Fixed search-VC task for project-VC, and added tests.

Change-Id: I8cc4a6a8383d8022f7ca681b65a002c8d9021d79
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 adae511..f885417 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
@@ -16,6 +16,7 @@
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
+import de.ids_mannheim.korap.constant.PredefinedUserGroup;
 import de.ids_mannheim.korap.constant.VirtualCorpusAccessStatus;
 import de.ids_mannheim.korap.entity.UserGroup;
 import de.ids_mannheim.korap.entity.UserGroup_;
@@ -24,6 +25,7 @@
 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.utils.ParameterChecker;
 
 @Transactional
@@ -177,6 +179,44 @@
         }
     }
 
+    public VirtualCorpusAccess retrievePublishedGroupAccess (int vcId)
+            throws KustvaktException {
+        ParameterChecker.checkIntegerValue(vcId, "vcId");
+
+        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<VirtualCorpusAccess> query =
+                builder.createQuery(VirtualCorpusAccess.class);
+
+        Root<VirtualCorpusAccess> access =
+                query.from(VirtualCorpusAccess.class);
+        Join<VirtualCorpusAccess, VirtualCorpus> accessVC =
+                access.join(VirtualCorpusAccess_.virtualCorpus);
+        Join<VirtualCorpusAccess, UserGroup> accessGroup =
+                access.join(VirtualCorpusAccess_.userGroup);
+
+        Predicate p = builder.and(
+                builder.equal(accessVC.get(VirtualCorpus_.id), vcId),
+                builder.equal(accessGroup.get(UserGroup_.id),
+                        PredefinedUserGroup.ALL.getId()),
+                builder.equal(access.get(VirtualCorpusAccess_.status),
+                        VirtualCorpusAccessStatus.HIDDEN),
+                builder.notEqual(access.get(VirtualCorpusAccess_.deletedBy),
+                        "NULL"));
+
+        query.select(access);
+        query.where(p);
+
+        try {
+            Query q = entityManager.createQuery(query);
+            return (VirtualCorpusAccess) q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND,
+                    "Auto group access  is not found for virtual corpus with id "
+                            + vcId);
+        }
+    }
+
     public void createAccessToVC (VirtualCorpus virtualCorpus,
             UserGroup userGroup, String createdBy,
             VirtualCorpusAccessStatus status) {
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
index a7690d7..3038d72 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
@@ -48,9 +48,9 @@
     private EntityManager entityManager;
 
     public int createVirtualCorpus (String name, VirtualCorpusType type,
-            CorpusAccess requiredAccess, String corpusQuery,
-            String definition, String description, String status,
-            String createdBy) throws KustvaktException {
+            CorpusAccess requiredAccess, String corpusQuery, String definition,
+            String description, String status, String createdBy)
+            throws KustvaktException {
 
         VirtualCorpus vc = new VirtualCorpus();
         vc.setName(name);
@@ -157,9 +157,9 @@
         Query q = entityManager.createQuery(query);
         return q.getResultList();
     }
-    
-    public List<VirtualCorpus> retrieveOwnerVCByType (String userId, VirtualCorpusType type)
-            throws KustvaktException {
+
+    public List<VirtualCorpus> retrieveOwnerVCByType (String userId,
+            VirtualCorpusType type) throws KustvaktException {
         ParameterChecker.checkStringValue(userId, "userId");
 
         CriteriaBuilder builder = entityManager.getCriteriaBuilder();
@@ -168,13 +168,11 @@
 
         Root<VirtualCorpus> virtualCorpus = query.from(VirtualCorpus.class);
         query.select(virtualCorpus);
-        
+
         Predicate p = builder.and(
                 builder.equal(virtualCorpus.get(VirtualCorpus_.createdBy),
                         userId),
-                builder.equal(virtualCorpus.get(VirtualCorpus_.type),
-                        type)
-                );
+                builder.equal(virtualCorpus.get(VirtualCorpus_.type), type));
         query.where(p);
 
         Query q = entityManager.createQuery(query);
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 8cce326..612ae24 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
@@ -205,4 +205,17 @@
         groupMemberDao.deleteMember(username, groupId, true);
     }
 
+
+    public boolean isMember (String username, UserGroup userGroup)
+            throws KustvaktException {
+        List<UserGroupMember> members =
+                groupMemberDao.retrieveMemberByGroupId(userGroup.getId());
+        for (UserGroupMember member : members) {
+            if (member.getUserId().equals(username)
+                    && member.getStatus().equals(GroupMemberStatus.ACTIVE)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
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 5bf6180..60c36bc 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
@@ -405,30 +405,45 @@
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
         VirtualCorpusType type = vc.getType();
 
-        if (!user.isAdmin()) {
+        if (!user.isAdmin() || !username.equals(vc.getCreatedBy())) {
             if (type.equals(VirtualCorpusType.PRIVATE)
-                    || type.equals(VirtualCorpusType.PROJECT)) {
+                    || (type.equals(VirtualCorpusType.PROJECT)
+                            && !hasAccess(username, vcId))) {
                 throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                         "Unauthorized operation for user: " + username,
                         username);
             }
+
             else if (VirtualCorpusType.PUBLISHED.equals(type)) {
-                // add user in auto group 
-                List<VirtualCorpusAccess> hiddenAccessList =
-                        accessDao.retrieveHiddenAccess(vcId);
-                for (VirtualCorpusAccess access : hiddenAccessList) {
-                    if (PredefinedUserGroup.ALL.getId() != access.getUserGroup()
-                            .getId()) {
-                        userGroupService.addUserToGroup(username,
-                                access.getUserGroup());
-                        break;
-                    }
+                // add user in the VC's auto group 
+                VirtualCorpusAccess access =
+                        accessDao.retrievePublishedGroupAccess(vcId);
+                UserGroup userGroup = access.getUserGroup();
+                if (userGroupService.isMember(username, userGroup)) {
+                    userGroupService.addUserToGroup(username, userGroup);
                 }
             }
+            // else VirtualCorpusType.PREDEFINED
         }
 
         String json = vc.getCorpusQuery();
         String statistics = krill.getStatistics(json);
         return converter.createVirtualCorpusDto(vc, statistics);
     }
+
+    private boolean hasAccess (String username, int vcId)
+            throws KustvaktException {
+        UserGroup userGroup;
+        List<VirtualCorpusAccess> accessList =
+                accessDao.retrieveActiveAccessByVC(vcId);
+        for (VirtualCorpusAccess access : accessList) {
+            userGroup = access.getUserGroup();
+            if (userGroupService.isMember(username, userGroup)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
 }