Added delete VC and get user group web-services.

Change-Id: Iaef203d73070d63e1a8a16f4228bd7281ca76d55
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index 528b8a1..d673427 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -135,7 +135,12 @@
 		// todo:
 		// user.addField(Attributes.HOST, context.getHostAddress());
 		// user.addField(Attributes.USER_AGENT, context.getUserAgent());
-		return entHandler.getAccount(username);
+		
+		//EM:copied from EntityDao
+		KorAPUser user = new KorAPUser(); // oder eigentlich new DemoUser oder new DefaultUser.
+        user.setUsername(username);
+        return user;
+//		return entHandler.getAccount(username);
 	}
 
 	public TokenContext refresh(TokenContext context) throws KustvaktException {
diff --git a/full/src/main/java/de/ids_mannheim/korap/constant/PredefinedRole.java b/full/src/main/java/de/ids_mannheim/korap/constant/PredefinedRole.java
index 29dd9d4..65b0fad 100644
--- a/full/src/main/java/de/ids_mannheim/korap/constant/PredefinedRole.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/PredefinedRole.java
@@ -1,7 +1,7 @@
 package de.ids_mannheim.korap.constant;
 
 public enum PredefinedRole {
-    GROUP_ADMIN(1), GROUP_MEMBER(2), VC_ADMIN(3), VC_MEMBER(4);
+    USER_GROUP_ADMIN(1), USER_GROUP_MEMBER(2), VC_ACCESS_ADMIN(3), VC_ACCESS_MEMBER(4);
     
     private int id;
     private String name;
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
index 915a1ce..3422de7 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -62,8 +62,8 @@
         entityManager.persist(group);
 
         List<Role> roles = new ArrayList<Role>(2);
-        roles.add(roleDao.retrieveRoleById(PredefinedRole.GROUP_ADMIN.getId()));
-        roles.add(roleDao.retrieveRoleById(PredefinedRole.VC_ADMIN.getId()));
+        roles.add(roleDao.retrieveRoleById(PredefinedRole.USER_GROUP_ADMIN.getId()));
+        roles.add(roleDao.retrieveRoleById(PredefinedRole.VC_ACCESS_ADMIN.getId()));
 
         UserGroupMember owner = new UserGroupMember();
         owner.setUserId(createdBy);
@@ -194,6 +194,16 @@
         return q.getResultList();
     }
 
+    public void retrieveGroupByVCId (String vcId) {
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<VirtualCorpusAccess> query =
+                criteriaBuilder.createQuery(VirtualCorpusAccess.class);
+
+        Root<VirtualCorpusAccess> root = query.from(VirtualCorpusAccess.class);
+
+
+    }
+    
     public void addVCToGroup (VirtualCorpus virtualCorpus, String createdBy,
             VirtualCorpusAccessStatus status, UserGroup group) {
         VirtualCorpusAccess accessGroup = new VirtualCorpusAccess();
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
index 1a80b92..c0cced2 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
@@ -16,6 +16,7 @@
 
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.entity.Role;
+import de.ids_mannheim.korap.entity.Role_;
 import de.ids_mannheim.korap.entity.UserGroupMember;
 import de.ids_mannheim.korap.entity.UserGroupMember_;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -102,7 +103,9 @@
         Predicate predicate = criteriaBuilder.and(
                 criteriaBuilder.equal(root.get(UserGroupMember_.group),
                         groupId),
-                criteriaBuilder.equal(memberRole.get("role_id"), roleId));
+                criteriaBuilder.notEqual(root.get(UserGroupMember_.status),
+                        GroupMemberStatus.DELETED),
+                criteriaBuilder.equal(memberRole.get(Role_.id), roleId));
 
         query.select(root);
         query.where(predicate);
@@ -117,8 +120,11 @@
 
         Root<UserGroupMember> root = query.from(UserGroupMember.class);
 
-        Predicate predicate = criteriaBuilder.and(criteriaBuilder
-                .equal(root.get(UserGroupMember_.group), groupId));
+        Predicate predicate = criteriaBuilder.and(
+                criteriaBuilder.equal(root.get(UserGroupMember_.group),
+                        groupId),
+                criteriaBuilder.notEqual(root.get(UserGroupMember_.status),
+                        GroupMemberStatus.DELETED));
 
         query.select(root);
         query.where(predicate);
diff --git a/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java b/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
new file mode 100644
index 0000000..10fc1c4
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
@@ -0,0 +1,16 @@
+package de.ids_mannheim.korap.dto;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class UserGroupDto {
+
+    private int id;
+    private String name;
+    private String owner;
+    private List<UserGroupMemberDto> members;
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupMemberDto.java b/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupMemberDto.java
new file mode 100644
index 0000000..1a5eda3
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupMemberDto.java
@@ -0,0 +1,15 @@
+package de.ids_mannheim.korap.dto;
+
+import java.util.List;
+
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class UserGroupMemberDto {
+    private String userId;
+    private GroupMemberStatus status;
+    private List<String> roles;
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dto/converter/UserGroupConverter.java b/full/src/main/java/de/ids_mannheim/korap/dto/converter/UserGroupConverter.java
new file mode 100644
index 0000000..de8b46a
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/converter/UserGroupConverter.java
@@ -0,0 +1,49 @@
+package de.ids_mannheim.korap.dto.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.dto.UserGroupDto;
+import de.ids_mannheim.korap.dto.UserGroupMemberDto;
+import de.ids_mannheim.korap.entity.Role;
+import de.ids_mannheim.korap.entity.UserGroup;
+import de.ids_mannheim.korap.entity.UserGroupMember;
+
+@Service
+public class UserGroupConverter {
+
+    public UserGroupDto createUserGroupDto (UserGroup group,
+            List<UserGroupMember> members) {
+
+        UserGroupDto dto = new UserGroupDto();
+        dto.setId(group.getId());
+        dto.setName(group.getName());
+        dto.setOwner(group.getCreatedBy());
+
+        if (members != null) {
+            ArrayList<UserGroupMemberDto> memberDtos =
+                    new ArrayList<>(members.size());
+            for (UserGroupMember member : members) {
+
+                UserGroupMemberDto memberDto = new UserGroupMemberDto();
+                memberDto.setUserId(member.getUserId());
+                memberDto.setStatus(member.getStatus());
+                List<String> roles = new ArrayList<>(member.getRoles().size());
+                for (Role r : member.getRoles()) {
+                    roles.add(r.getName());
+                }
+                memberDto.setRoles(roles);
+                memberDtos.add(memberDto);
+            }
+            dto.setMembers(memberDtos);
+        }
+        else {
+            dto.setMembers(new ArrayList<UserGroupMemberDto>());
+        }
+
+        return dto;
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
index a4e9598..2bda7aa 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
@@ -55,7 +55,7 @@
     @JoinColumn(name = "group_id")
     private UserGroup group;
 
-    /** Information about roles is deemed always necessary to describe a member.
+    /** Information about roles is deemed to be always necessary to describe a member.
      * 
      */
     @ManyToMany(fetch = FetchType.EAGER)
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
new file mode 100644
index 0000000..9c18314
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -0,0 +1,56 @@
+package de.ids_mannheim.korap.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.constant.PredefinedRole;
+import de.ids_mannheim.korap.dao.UserGroupDao;
+import de.ids_mannheim.korap.dao.UserGroupMemberDao;
+import de.ids_mannheim.korap.dto.UserGroupDto;
+import de.ids_mannheim.korap.dto.converter.UserGroupConverter;
+import de.ids_mannheim.korap.entity.UserGroup;
+import de.ids_mannheim.korap.entity.UserGroupMember;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+
+@Service
+public class UserGroupService {
+
+    @Autowired
+    private UserGroupDao userGroupDao;
+    @Autowired
+    private UserGroupMemberDao groupMemberDao;
+    @Autowired
+    private UserGroupConverter converter;
+
+
+    public List<UserGroupDto> retrieveUserGroup (String username)
+            throws KustvaktException {
+
+        List<UserGroup> userGroups =
+                userGroupDao.retrieveGroupByUserId(username);
+        
+        ArrayList<UserGroupDto> dtos = new ArrayList<>(userGroups.size());
+        
+        List<UserGroupMember> groupAdmins;
+        for (UserGroup group : userGroups) {
+            groupAdmins = groupMemberDao.retrieveMemberByRole(group.getId(),
+                    PredefinedRole.USER_GROUP_ADMIN.getId());
+            
+            List<UserGroupMember> members = null;
+            for (UserGroupMember admin : groupAdmins) {
+                if (admin.getUserId().equals(username)) {
+                    members = groupMemberDao
+                            .retrieveMemberByGroupId(group.getId());
+                    break;
+                }
+            }
+            dtos.add(converter.createUserGroupDto(group, members));
+        }
+
+        return dtos;
+    }
+
+}
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 4cf831a..8916477 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
@@ -27,8 +27,16 @@
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
 import de.ids_mannheim.korap.web.SearchKrill;
+import de.ids_mannheim.korap.web.controller.VirtualCorpusController;
 import de.ids_mannheim.korap.web.input.VirtualCorpusFromJson;
 
+/** VirtualCorpusService handles the logic behind {@link VirtualCorpusController}. 
+ *  It communicates with {@link VirtualCorpusDao} and returns DTO to  
+ *  {@link VirtualCorpusController}.
+ * 
+ * @author margaretha
+ *
+ */
 @Service
 public class VirtualCorpusService {
 
@@ -117,13 +125,38 @@
 
         Set<VirtualCorpus> vcs = dao.retrieveVCByUser(username);
         ArrayList<VirtualCorpusDto> dtos = new ArrayList<>(vcs.size());
-        
+
         for (VirtualCorpus vc : vcs) {
             String json = vc.getCollectionQuery();
             String statistics = krill.getStatistics(json);
-            VirtualCorpusDto vcDto = converter.createVirtualCorpusDto(vc, statistics);
+            VirtualCorpusDto vcDto =
+                    converter.createVirtualCorpusDto(vc, statistics);
             dtos.add(vcDto);
         }
         return dtos;
     }
+
+    /** Only admin and the owner of the virtual corpus are allowed to 
+     *  delete a virtual corpus.
+     *  
+     *  EM: are VC-access admins also allowed to delete?
+     * 
+     * @param username username
+     * @param vcId virtual corpus id
+     * @throws KustvaktException
+     */
+    public void deleteVC (String username, int vcId)
+            throws KustvaktException {
+
+        User user = authManager.getUser(username);
+        VirtualCorpus vc = dao.retrieveVCById(vcId);
+
+        if (user.isAdmin() || vc.getCreatedBy().equals(username)) {
+            dao.deleteVirtualCorpus(vcId);
+        }
+        else {
+            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                    "Unauthorized operation for user: " + username, username);
+        }
+    }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index 5ab5a78..328a3d4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -36,9 +36,9 @@
 import com.sun.jersey.spi.container.ResourceFilters;
 
 import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.KustvaktConfiguration.BACKENDS;
-import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
new file mode 100644
index 0000000..7f888b1
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -0,0 +1,69 @@
+package de.ids_mannheim.korap.web.controller;
+
+import java.util.List;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.sun.jersey.spi.container.ResourceFilters;
+
+import de.ids_mannheim.korap.dto.UserGroupDto;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.service.UserGroupService;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.FullResponseHandler;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+@Controller
+@Path("group")
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+@ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+        PiwikFilter.class })
+public class UserGroupController {
+
+    private static Logger jlog =
+            LoggerFactory.getLogger(UserGroupController.class);
+
+    @Autowired
+    private FullResponseHandler responseHandler;
+    @Autowired
+    private UserGroupService service;
+    
+    @GET
+    @Path("user")
+    public Response getUserGroup (@Context SecurityContext securityContext){
+        String result;
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            if (context.isDemo()) {
+                throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                        "Operation is not permitted for user: "
+                                + context.getUsername(),
+                        context.getUsername());
+            }
+
+            List<UserGroupDto> dtos =
+                    service.retrieveUserGroup(context.getUsername());
+            result = JsonUtils.toJSON(dtos);
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index 81f293b..3f122f3 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -2,6 +2,7 @@
 
 import java.util.List;
 
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -77,23 +78,23 @@
         return Response.ok().build();
     }
 
+    // EM: nicer URL with username?
     @GET
     @Path("user")
-    public Response getUserVC (@Context SecurityContext securityContext,
-            @QueryParam("userId") String userId) throws KustvaktException {
-
+    public Response getUserVC (@Context SecurityContext securityContext){
+        String result;
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
-        if (context.isDemo()) {
-            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
-                    "Operation is not permitted for user: "
-                            + context.getUsername(),
-                    context.getUsername());
-        }
-
-        List<VirtualCorpusDto> dtos = service.retrieveUserVC(context.getUsername());
-        String result;
         try {
+            if (context.isDemo()) {
+                throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                        "Operation is not permitted for user: "
+                                + context.getUsername(),
+                        context.getUsername());
+            }
+
+            List<VirtualCorpusDto> dtos =
+                    service.retrieveUserVC(context.getUsername());
             result = JsonUtils.toJSON(dtos);
         }
         catch (KustvaktException e) {
@@ -102,4 +103,41 @@
         return Response.ok(result).build();
     }
 
+    //    @POST
+    //    @Path("edit")
+    //    public Response editVC (@Context SecurityContext securityContext,
+    //            String json) throws KustvaktException {
+    //        TokenContext context =
+    //                (TokenContext) securityContext.getUserPrincipal();
+    //        if (context.isDemo()) {
+    //            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+    //                    "Operation is not permitted for user: "
+    //                            + context.getUsername(),
+    //                    context.getUsername());
+    //        }
+    //
+    //        return Response.ok().build();
+    //    }
+
+    @DELETE
+    @Path("delete")
+    public Response deleteVC (@Context SecurityContext securityContext,
+            @QueryParam("vcId") int vcId) {
+        try {
+            TokenContext context =
+                    (TokenContext) securityContext.getUserPrincipal();
+            if (context.isDemo()) {
+                throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                        "Operation is not permitted for user: "
+                                + context.getUsername(),
+                        context.getUsername());
+            }
+            service.deleteVC(context.getUsername(), vcId);
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/dao/RolePrivilegeDaoTest.java b/full/src/test/java/de/ids_mannheim/korap/dao/RolePrivilegeDaoTest.java
index 4c956ae..d7317a6 100644
--- a/full/src/test/java/de/ids_mannheim/korap/dao/RolePrivilegeDaoTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/dao/RolePrivilegeDaoTest.java
@@ -27,7 +27,7 @@
 
     @Test
     public void retrievePredefinedRole () {
-        Role r = roleDao.retrieveRoleById(PredefinedRole.GROUP_ADMIN.getId());
+        Role r = roleDao.retrieveRoleById(PredefinedRole.USER_GROUP_ADMIN.getId());
         assertEquals(1, r.getId());
     }
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java b/full/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
index e978e49..66e2b79 100644
--- a/full/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
@@ -66,8 +66,8 @@
         // member roles
         List<Role> roles = roleDao.retrieveRoleByGroupMemberId(m.getId());
         assertEquals(2, roles.size());
-        assertEquals(PredefinedRole.GROUP_ADMIN.getId(), roles.get(0).getId());
-        assertEquals(PredefinedRole.VC_ADMIN.getId(), roles.get(1).getId());
+        assertEquals(PredefinedRole.USER_GROUP_ADMIN.getId(), roles.get(0).getId());
+        assertEquals(PredefinedRole.VC_ACCESS_ADMIN.getId(), roles.get(1).getId());
 
         //retrieve VC by group
         List<VirtualCorpus> vc = virtualCorpusDao.retrieveVCByGroup(groupId);
@@ -93,8 +93,8 @@
         UserGroupMember m = members.get(1);
         List<Role> roles = m.getRoles();
         assertEquals(2, roles.size());
-        assertEquals(PredefinedRole.GROUP_MEMBER.getId(), roles.get(0).getId());
-        assertEquals(PredefinedRole.VC_MEMBER.getId(), roles.get(1).getId());
+        assertEquals(PredefinedRole.USER_GROUP_MEMBER.getId(), roles.get(0).getId());
+        assertEquals(PredefinedRole.VC_ACCESS_MEMBER.getId(), roles.get(1).getId());
     }
 
     @Test
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserGroupServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserGroupServiceTest.java
new file mode 100644
index 0000000..1fde8bd
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserGroupServiceTest.java
@@ -0,0 +1,84 @@
+package de.ids_mannheim.korap.web.service.full;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.ClientResponse.Status;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class UserGroupServiceTest extends SpringJerseyTest {
+
+    @Autowired
+    private HttpAuthorizationHandler handler;
+
+    // dory is a group admin in dory group
+    @Test
+    public void testRetrieveDoryGroups () throws KustvaktException {
+        ClientResponse response = resource().path("group").path("user")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue("dory",
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+        String entity = response.getEntity(String.class);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+//        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        
+        assertEquals(1, node.at("/0/id").asInt());
+        assertEquals("dory group", node.at("/0/name").asText());
+        assertEquals("dory", node.at("/0/owner").asText());
+        assertEquals(3, node.at("/0/members").size());
+    }
+    
+    // nemo is a group member in dory group
+    @Test
+    public void testRetrieveNemoGroups () throws KustvaktException {
+        ClientResponse response = resource().path("group").path("user")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue("nemo",
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+        String entity = response.getEntity(String.class);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+//        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        
+        assertEquals(1, node.at("/0/id").asInt());
+        assertEquals("dory group", node.at("/0/name").asText());
+        assertEquals("dory", node.at("/0/owner").asText());
+        // group members are not allowed to see other members
+        assertEquals(0, node.at("/0/members").size());
+    }
+    
+    @Test
+    public void testRetrieveUserGroupUnauthorized () throws KustvaktException {
+        ClientResponse response = resource().path("group").path("user")
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+        String entity = response.getEntity(String.class);
+//        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        
+        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Operation is not permitted for user: guest",
+                node.at("/errors/0/1").asText());
+        
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/VirtualCorpusServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/VirtualCorpusServiceTest.java
index 5f9a551..6c5cd74 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/VirtualCorpusServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/VirtualCorpusServiceTest.java
@@ -34,6 +34,24 @@
 
     @Autowired
     private HttpAuthorizationHandler handler;
+    
+    private void checkWWWAuthenticateHeader (ClientResponse response) {
+        Set<Entry<String, List<String>>> headers =
+                response.getHeaders().entrySet();
+
+        for (Entry<String, List<String>> header : headers) {
+            if (header.getKey().equals(ContainerRequest.WWW_AUTHENTICATE)) {
+                assertEquals("Api realm=\"Kustvakt\"",
+                        header.getValue().get(0));
+                assertEquals("Session realm=\"Kustvakt\"",
+                        header.getValue().get(1));
+                assertEquals("Bearer realm=\"Kustvakt\"",
+                        header.getValue().get(2));
+                assertEquals("Basic realm=\"Kustvakt\"",
+                        header.getValue().get(3));
+            }
+        }
+    }
 
     @Test
     public void testRetrieveUserVC () throws UniformInterfaceException,
@@ -43,43 +61,91 @@
                         handler.createBasicAuthorizationHeaderValue("dory",
                                 "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                
+
                 .get(ClientResponse.class);
         String entity = response.getEntity(String.class);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
-//        System.out.println(entity);
+        //        System.out.println(entity);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(3, node.size());
     }
+
     @Test
-    public void testStoreVC () throws KustvaktException {
+    public void testRetrieveUserVCUnauthorized ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
+        ClientResponse response = resource().path("vc").path("user")
+                .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.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Operation is not permitted for user: guest",
+                node.at("/errors/0/1").asText());
+        
+        checkWWWAuthenticateHeader(response);
+    }
+
+    @Test
+    public void testStoreDeleteVC () throws KustvaktException {
         String json =
                 "{\"name\": \"new vc\",\"type\": \"PRIVATE\",\"createdBy\": "
                         + "\"test class\",\"collectionQuery\": \"corpusSigle=GOE\"}";
 
         ClientResponse response = resource().path("vc").path("store")
                 .header(Attributes.AUTHORIZATION,
-                        handler.createBasicAuthorizationHeaderValue("test class",
-                                "pass"))
+                        handler.createBasicAuthorizationHeaderValue(
+                                "test class", "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").entity(json)
                 .post(ClientResponse.class);
         String entity = response.getEntity(String.class);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
 
+        // retrieve user VC
         response = resource().path("vc").path("user")
-                .queryParam("username", "test class")
                 .header(Attributes.AUTHORIZATION,
-                        handler.createBasicAuthorizationHeaderValue("test class",
-                                "pass"))
+                        handler.createBasicAuthorizationHeaderValue(
+                                "test class", "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                
+
                 .get(ClientResponse.class);
         entity = response.getEntity(String.class);
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());   
-//        System.out.println(entity);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        //        System.out.println(entity);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(2, node.size());
         assertEquals("new vc", node.get(1).get("name").asText());
+
+        String vcId = node.get(1).get("id").asText();
+
+        // delete new VC
+        resource().path("vc").path("delete").queryParam("vcId", vcId)
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue(
+                                "test class", "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+
+                .delete(ClientResponse.class);
+        //        entity = response.getEntity(String.class);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        // retrieve user VC
+        response = resource().path("vc").path("user")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue(
+                                "test class", "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+
+                .get(ClientResponse.class);
+        entity = response.getEntity(String.class);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        //        System.out.println(entity);
+        node = JsonUtils.readTree(entity);
+        assertEquals(1, node.size());
     }
 
     @Test
@@ -109,6 +175,8 @@
         assertEquals(StatusCodes.EXPIRED, node.at("/errors/0/0").asInt());
         assertEquals("Authentication token is expired",
                 node.at("/errors/0/1").asText());
+        
+        checkWWWAuthenticateHeader(response);
     }
 
     @Test
@@ -122,28 +190,14 @@
 
         assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
 
-        Set<Entry<String, List<String>>> headers =
-                response.getHeaders().entrySet();
-
-        for (Entry<String, List<String>> header : headers) {
-            if (header.getKey().equals(ContainerRequest.WWW_AUTHENTICATE)) {
-                assertEquals("Api realm=\"Kustvakt\"",
-                        header.getValue().get(0));
-                assertEquals("Session realm=\"Kustvakt\"",
-                        header.getValue().get(1));
-                assertEquals("Bearer realm=\"Kustvakt\"",
-                        header.getValue().get(2));
-                assertEquals("Basic realm=\"Kustvakt\"",
-                        header.getValue().get(3));
-            }
-        }
-
         String entity = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(StatusCodes.AUTHORIZATION_FAILED,
                 node.at("/errors/0/0").asInt());
         assertEquals("Operation is not permitted for user: guest",
                 node.at("/errors/0/1").asText());
+        
+        checkWWWAuthenticateHeader(response);
     }
 
     @Test
@@ -155,7 +209,7 @@
         ClientResponse response = resource().path("vc").path("store")
                 .entity(json).post(ClientResponse.class);
         String entity = response.getEntity(String.class);
-                System.out.println(entity);
+        //        System.out.println(entity);
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
 
         JsonNode node = JsonUtils.readTree(entity);
@@ -166,4 +220,27 @@
                         + "VirtualCorpusType` from String \"PRIVAT\": value not one of "
                         + "declared Enum instance names"));
     }
+
+    @Test
+    public void testDeleteVCUnauthorized () throws KustvaktException {
+        ClientResponse response =
+                resource().path("vc").path("delete").queryParam("vcId", "1")
+                        .header(Attributes.AUTHORIZATION,
+                                handler.createBasicAuthorizationHeaderValue(
+                                        "test class", "pass"))
+                        .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+
+                        .delete(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());
+        assertEquals("Unauthorized operation for user: test class",
+                node.at("/errors/0/1").asText());
+        
+        checkWWWAuthenticateHeader(response);
+    }
 }