Implemented delete user-group and member tasks.

Change-Id: Iacb799ca03234fbbd4b6cc06126cb78ed3521aad
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 d673427..46649eb 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
@@ -324,7 +324,7 @@
 		}
 
 		boolean isAdmin = adminHandler.isAdmin(unknown.getId());
-		unknown.setAdmin(isAdmin);
+		unknown.setSystemAdmin(isAdmin);
 		jlog.debug("Authentication: found username " + unknown.getUsername());
 
 		if (unknown instanceof KorAPUser) {
@@ -697,7 +697,7 @@
 
 		String o = (String) attributes.get(Attributes.IS_ADMIN);
 		boolean b = Boolean.parseBoolean(o);
-		user.setAdmin(b);
+		user.setSystemAdmin(b);
 
 		try {
 			UserDetails details = new UserDetails();
@@ -708,7 +708,7 @@
 
 			jlog.info("Creating new user account for user {}", user.getUsername());
 			entHandler.createAccount(user);
-			if (user.isAdmin() && user instanceof KorAPUser) {
+			if (user.isSystemAdmin() && user instanceof KorAPUser) {
 				adminHandler.addAccount(user);
 				user.setCorpusAccess(CorpusAccess.ALL);
 			}
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 6bd621f..6885f3d 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
@@ -172,8 +172,10 @@
                         UserGroupStatus.ACTIVE),
                 criteriaBuilder.equal(members.get(UserGroupMember_.userId),
                         userId),
-                criteriaBuilder.equal(members.get(UserGroupMember_.status),
-                        GroupMemberStatus.ACTIVE));
+                criteriaBuilder.notEqual(members.get(UserGroupMember_.status),
+                        GroupMemberStatus.DELETED));
+//                criteriaBuilder.equal(members.get(UserGroupMember_.status),
+//                        GroupMemberStatus.ACTIVE));
 
 
         query.select(root);
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
index 10fc1c4..6b3e8b6 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/UserGroupDto.java
@@ -2,6 +2,7 @@
 
 import java.util.List;
 
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -13,4 +14,5 @@
     private String name;
     private String owner;
     private List<UserGroupMemberDto> members;
+    private GroupMemberStatus userMemberStatus;
 }
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
index 8925d20..273677b 100644
--- 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
@@ -5,6 +5,7 @@
 
 import org.springframework.stereotype.Component;
 
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.dto.UserGroupDto;
 import de.ids_mannheim.korap.dto.UserGroupMemberDto;
 import de.ids_mannheim.korap.entity.Role;
@@ -15,12 +16,13 @@
 public class UserGroupConverter {
 
     public UserGroupDto createUserGroupDto (UserGroup group,
-            List<UserGroupMember> members) {
+            List<UserGroupMember> members, GroupMemberStatus userMemberStatus) {
 
         UserGroupDto dto = new UserGroupDto();
         dto.setId(group.getId());
         dto.setName(group.getName());
         dto.setOwner(group.getCreatedBy());
+        dto.setUserMemberStatus(userMemberStatus);
 
         if (members != null) {
             ArrayList<UserGroupMemberDto> memberDtos =
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 c238ae4..02cff45 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
@@ -66,30 +66,44 @@
         Collections.sort(userGroups);
         ArrayList<UserGroupDto> dtos = new ArrayList<>(userGroups.size());
 
-        List<UserGroupMember> groupAdmins;
+        UserGroupMember userAsMember;
+        List<UserGroupMember> members;
         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));
+            members = retrieveMembers(group.getId(), username);
+            userAsMember =
+                    groupMemberDao.retrieveMemberById(username, group.getId());
+            dtos.add(converter.createUserGroupDto(group, members,
+                    userAsMember.getStatus()));
         }
 
         return dtos;
     }
 
+    private List<UserGroupMember> retrieveMembers (int groupId, String username)
+            throws KustvaktException {
+        List<UserGroupMember> groupAdmins = groupMemberDao.retrieveMemberByRole(
+                groupId, PredefinedRole.USER_GROUP_ADMIN.getId());
+
+        List<UserGroupMember> members = null;
+        for (UserGroupMember admin : groupAdmins) {
+            if (admin.getUserId().equals(username)) {
+                members = groupMemberDao.retrieveMemberByGroupId(groupId);
+                break;
+            }
+        }
+        
+        return members;
+    }
+
     public UserGroup retrieveUserGroupById (int groupId)
             throws KustvaktException {
         return userGroupDao.retrieveGroupById(groupId);
     }
 
+    public UserGroup retrieveHiddenGroup (int vcId) throws KustvaktException {
+        return userGroupDao.retrieveHiddenGroupByVC(vcId);
+    }
+
     public List<UserGroupMember> retrieveVCAccessAdmins (UserGroup userGroup)
             throws KustvaktException {
         List<UserGroupMember> groupAdmins = groupMemberDao.retrieveMemberByRole(
@@ -104,6 +118,15 @@
         return groupAdmins;
     }
 
+    private void setMemberRoles () {
+        if (memberRoles == null) {
+            memberRoles = new ArrayList<Role>(2);
+            memberRoles.add(roleDao.retrieveRoleById(
+                    PredefinedRole.USER_GROUP_MEMBER.getId()));
+            memberRoles.add(roleDao
+                    .retrieveRoleById(PredefinedRole.VC_ACCESS_MEMBER.getId()));
+        }
+    }
 
     /** Group owner is automatically added when creating a group. 
      *  Do not include owners in group members. 
@@ -122,43 +145,37 @@
      * @see /full/src/main/resources/db/predefined/V3.2__insert_predefined_roles.sql
      * 
      * @param groupJson UserGroupJson object from json
-     * @param username the user creating the group
+     * @param createdBy the user creating the group
      * @throws KustvaktException
      * 
      * 
      */
-    public void createUserGroup (UserGroupJson groupJson, String username)
+    public void createUserGroup (UserGroupJson groupJson, String createdBy)
             throws KustvaktException {
 
-        int groupId = userGroupDao.createGroup(groupJson.getName(), username,
+        int groupId = userGroupDao.createGroup(groupJson.getName(), createdBy,
                 UserGroupStatus.ACTIVE);
-        UserGroup group = userGroupDao.retrieveGroupById(groupId);
+        UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
 
         setMemberRoles();
 
-        UserGroupMember m;
+
         for (String memberId : groupJson.getMembers()) {
-            if (memberId.equals(username)) {
+            if (memberId.equals(createdBy)) {
                 // skip owner, already added while creating group.
                 continue;
             }
-
-            m = new UserGroupMember();
-            m.setUserId(memberId);
-            m.setCreatedBy(username);
-            m.setGroup(group);
-            m.setStatus(GroupMemberStatus.PENDING);
-            m.setRoles(memberRoles);
+            addGroupMember(memberId, userGroup, createdBy,
+                    GroupMemberStatus.PENDING);
         }
     }
 
-    private void setMemberRoles () {
-        if (memberRoles == null) {
-            memberRoles = new ArrayList<Role>(2);
-            memberRoles.add(roleDao.retrieveRoleById(
-                    PredefinedRole.USER_GROUP_MEMBER.getId()));
-            memberRoles.add(roleDao
-                    .retrieveRoleById(PredefinedRole.VC_ACCESS_MEMBER.getId()));
+    public void deleteGroup (int groupId, String username)
+            throws KustvaktException {
+        User user = authManager.getUser(username);
+        UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
+        if (userGroup.getCreatedBy().equals(username) || user.isSystemAdmin()) {
+            userGroupDao.deleteGroup(groupId, username, false);
         }
     }
 
@@ -191,7 +208,7 @@
      * @param status the status of the membership
      * @throws KustvaktException
      */
-    public void addUserToGroup (String username, UserGroup userGroup,
+    public void addGroupMember (String username, UserGroup userGroup,
             String createdBy, GroupMemberStatus status)
             throws KustvaktException {
 
@@ -227,11 +244,12 @@
             return false;
         }
 
-        GroupMemberStatus memberStatus = existingMember.getStatus();
-        if (memberStatus.equals(status)) {
+        GroupMemberStatus existingStatus = existingMember.getStatus();
+        if (existingStatus.equals(GroupMemberStatus.ACTIVE)
+                || existingStatus.equals(status)) {
             return true;
         }
-        else if (memberStatus.equals(GroupMemberStatus.DELETED)) {
+        else if (existingStatus.equals(GroupMemberStatus.DELETED)) {
             // hard delete
             groupMemberDao.deleteMember(username, groupId, "system", false);
         }
@@ -242,15 +260,15 @@
     public void addUsersToGroup (UserGroupJson group, String username)
             throws KustvaktException {
         int groupId = group.getId();
-        List<String> members = group.getMembers();
+        String[] members = group.getMembers();
         ParameterChecker.checkIntegerValue(groupId, "id");
         ParameterChecker.checkObjectValue(members, "members");
 
         UserGroup userGroup = retrieveUserGroupById(groupId);
         User user = authManager.getUser(username);
-        if (isUserGroupAdmin(username, userGroup) || user.isAdmin()) {
+        if (isUserGroupAdmin(username, userGroup) || user.isSystemAdmin()) {
             for (String memberName : members) {
-                addUserToGroup(memberName, userGroup, username,
+                addGroupMember(memberName, userGroup, username,
                         GroupMemberStatus.PENDING);
             }
         }
@@ -311,9 +329,23 @@
         return false;
     }
 
-    public UserGroup retrieveHiddenGroup (int vcId) throws KustvaktException {
-        return userGroupDao.retrieveHiddenGroupByVC(vcId);
+    public void deleteGroupMember (String memberId, int groupId,
+            String deletedBy) throws KustvaktException {
+        User user = authManager.getUser(deletedBy);
+        UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
+        if (memberId.equals(userGroup.getCreatedBy())) {
+            throw new KustvaktException(StatusCodes.NOT_ALLOWED,
+                    "Operation " + "'delete group owner'" + "is not allowed.",
+                    "delete group owner");
+        }
+        else if (isUserGroupAdmin(deletedBy, userGroup)
+                || user.isSystemAdmin()) {
+            groupMemberDao.deleteMember(memberId, groupId, deletedBy, false);
+        }
+        else {
+            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                    "Unauthorized operation for user: " + deletedBy, deletedBy);
+        }
     }
 
-
 }
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 832dca0..b4e7fbc 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
@@ -14,7 +14,6 @@
 
 import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
-import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.constant.VirtualCorpusAccessStatus;
 import de.ids_mannheim.korap.constant.VirtualCorpusType;
 import de.ids_mannheim.korap.dao.VirtualCorpusAccessDao;
@@ -110,7 +109,7 @@
         User user = authManager.getUser(username);
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
 
-        if (vc.getCreatedBy().equals(username) || user.isAdmin()) {
+        if (vc.getCreatedBy().equals(username) || user.isSystemAdmin()) {
             vcDao.deleteVirtualCorpus(vcId);
         }
         else {
@@ -126,7 +125,7 @@
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
 
         User user = authManager.getUser(username);
-        if (!username.equals(vc.getCreatedBy()) && !user.isAdmin()) {
+        if (!username.equals(vc.getCreatedBy()) && !user.isSystemAdmin()) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -192,7 +191,7 @@
         User user = authManager.getUser(username);
 
         if (vc.getType().equals(VirtualCorpusType.PREDEFINED)
-                && !user.isAdmin()) {
+                && !user.isSystemAdmin()) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -266,20 +265,22 @@
         User user = authManager.getUser(username);
 
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
-        if (!username.equals(vc.getCreatedBy()) && !user.isAdmin()) {
+        if (!username.equals(vc.getCreatedBy()) && !user.isSystemAdmin()) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
 
         UserGroup userGroup = userGroupService.retrieveUserGroupById(groupId);
 
-        if (!isVCAccessAdmin(userGroup, username) && !user.isAdmin()) {
+        if (!isVCAccessAdmin(userGroup, username) && !user.isSystemAdmin()) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
         else {
             accessDao.createAccessToVC(vc, userGroup, username,
                     VirtualCorpusAccessStatus.ACTIVE);
+            vcDao.editVirtualCorpus(vc, null, VirtualCorpusType.PUBLISHED, null,
+                    null, null, null, null);
         }
     }
 
@@ -304,7 +305,7 @@
                 userGroupService.retrieveVCAccessAdmins(userGroup);
 
         User user = authManager.getUser(username);
-        if (!user.isAdmin()) {
+        if (!user.isSystemAdmin()) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -315,7 +316,7 @@
 
         List<VirtualCorpusAccess> accessList;
         User user = authManager.getUser(username);
-        if (user.isAdmin()) {
+        if (user.isSystemAdmin()) {
             accessList = accessDao.retrieveAllAccessByVC(vcId);
         }
         else {
@@ -338,7 +339,7 @@
         UserGroup userGroup = userGroupService.retrieveUserGroupById(groupId);
 
         List<VirtualCorpusAccess> accessList;
-        if (user.isAdmin()) {
+        if (user.isSystemAdmin()) {
             accessList = accessDao.retrieveAllAccessByGroup(groupId);
         }
         else if (isVCAccessAdmin(userGroup, username)) {
@@ -359,7 +360,7 @@
 
         VirtualCorpusAccess access = accessDao.retrieveAccessById(accessId);
         UserGroup userGroup = access.getUserGroup();
-        if (isVCAccessAdmin(userGroup, username) || user.isAdmin()) {
+        if (isVCAccessAdmin(userGroup, username) || user.isSystemAdmin()) {
             accessDao.deleteAccess(access, username);
         }
         else {
@@ -376,7 +377,7 @@
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
         VirtualCorpusType type = vc.getType();
 
-        if (!user.isAdmin() && !username.equals(vc.getCreatedBy())) {
+        if (!user.isSystemAdmin() && !username.equals(vc.getCreatedBy())) {
             if (type.equals(VirtualCorpusType.PRIVATE)
                     || (type.equals(VirtualCorpusType.PROJECT)
                             && !hasAccess(username, vcId))) {
@@ -392,9 +393,9 @@
                 //                UserGroup userGroup = access.getUserGroup();
                 UserGroup userGroup =
                         userGroupService.retrieveHiddenGroup(vcId);
-//                if (!userGroupService.isMember(username, userGroup)) {
-                try{
-                    userGroupService.addUserToGroup(username, userGroup,
+                //                if (!userGroupService.isMember(username, userGroup)) {
+                try {
+                    userGroupService.addGroupMember(username, userGroup,
                             "system", GroupMemberStatus.ACTIVE);
                 }
                 catch (KustvaktException e) {
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
index 8679437..2ddec6f 100644
--- 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
@@ -3,11 +3,13 @@
 import java.util.List;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -31,13 +33,14 @@
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.input.UserGroupJson;
 
-/** UserGroupController defines web APIs related to user groups, 
- *  such as creating a user group,  listing groups of a user, 
- *  adding members to a group and subscribing (confirming an 
- *  invitation) to a group. 
- *  
- *  These APIs are only available to logged-in users.
- *   
+/**
+ * UserGroupController defines web APIs related to user groups,
+ * such as creating a user group, listing groups of a user,
+ * adding members to a group and subscribing (confirming an
+ * invitation) to a group.
+ * 
+ * These APIs are only available to logged-in users.
+ * 
  * @author margaretha
  *
  */
@@ -95,7 +98,7 @@
     @POST
     @Path("create")
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response createGroup (@Context SecurityContext securityContext,
+    public Response createUserGroup (@Context SecurityContext securityContext,
             UserGroupJson group) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
@@ -108,8 +111,50 @@
         }
     }
 
+    @DELETE
+    @Path("delete")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response deleteUserGroup (
+            @Context SecurityContext securityContext,
+            @QueryParam("groupId") int groupId) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            service.deleteGroup(groupId, context.getUsername());
+            return Response.ok().build();
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+    }
+    
+    /** Group owner cannot be deleted.
+     * 
+     * @param securityContext
+     * @param memberId a username of a group member
+     * @param groupId a group id
+     * @return if successful, HTTP response status OK
+     */
+    @DELETE
+    @Path("member/delete")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response deleteUserFromGroup (
+            @Context SecurityContext securityContext,
+            @QueryParam("memberId") String memberId,
+            @QueryParam("groupId") int groupId) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            service.deleteGroupMember(memberId, groupId, context.getUsername());
+            return Response.ok().build();
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+    }
+
     @POST
-    @Path("add")
+    @Path("member/invite")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response addUserToGroup (@Context SecurityContext securityContext,
             UserGroupJson group) {
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
index b1cc781..bac128c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
@@ -71,7 +71,7 @@
             // EM: fix me: AuthenticationType based on header value
             User user = authManager.authenticate(AuthenticationMethod.LDAP,
                     data.getUsername(), data.getPassword(), attributes);
-            if (!user.isAdmin()) {
+            if (!user.isSystemAdmin()) {
                 throw new KustvaktException(StatusCodes.AUTHENTICATION_FAILED,
                         "Admin authentication failed.");
             }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
index 758baf8..4cc7f99 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
@@ -44,7 +44,7 @@
         if (context == null || context.isDemo()) {
             throw kustvaktResponseHandler.throwit(new KustvaktException(
                     StatusCodes.AUTHORIZATION_FAILED,
-                    "Operation is not permitted for user: guest", "guest"));
+                    "Unauthorized operation for user: guest", "guest"));
         }
 
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/UserGroupJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/UserGroupJson.java
index 87f17cb..e3c25bd 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/UserGroupJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/UserGroupJson.java
@@ -1,7 +1,5 @@
 package de.ids_mannheim.korap.web.input;
 
-import java.util.List;
-
 import lombok.Getter;
 import lombok.Setter;
 
@@ -11,5 +9,5 @@
 
     private int id;
     private String name;
-    private List<String> members;
+    private String[] members;
 }