Remove soft delete group member (#765)

Change-Id: I371f47e17dafd41f4d1dceaf0cae5a94491d980c
diff --git a/Changes b/Changes
index 811c827..8b05de4 100644
--- a/Changes
+++ b/Changes
@@ -8,6 +8,7 @@
 - Update share-query and query-access web-services (#763)
 - Add new web-service: delete role by query and group (#763)
 - Remove soft delete group and group status deleted (#765)
+- Remove soft delete group member and member status deleted (#765)
 
 # version 0.74
 
diff --git a/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
index 0b92706..6a55ece 100644
--- a/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
@@ -47,9 +47,6 @@
 
     private String authenticationScheme;
 
-    private boolean isSoftDeleteAutoGroup;
-    private boolean isSoftDeleteGroupMember;
-
     private EncryptionIface.Encryption secureHashAlgorithm;
 
     private AuthenticationMethod OAuth2passwordAuthentication;
@@ -88,7 +85,6 @@
 
         // EM: pattern for matching availability in Krill matches
         setLicensePatterns(properties);
-        setDeleteConfiguration(properties);
         setMailConfiguration(properties);
         ldapConfig = properties.getProperty("ldap.config");
 
@@ -168,19 +164,6 @@
         }
     }
 
-    private void setDeleteConfiguration (Properties properties) {
-//        setSoftDeleteGroup(
-//                parseDeleteConfig(properties.getProperty("delete.group", "")));
-        setSoftDeleteAutoGroup(parseDeleteConfig(
-                properties.getProperty("delete.auto.group", "")));
-        setSoftDeleteGroupMember(parseDeleteConfig(
-                properties.getProperty("delete.group.member", "")));
-    }
-
-    private boolean parseDeleteConfig (String deleteConfig) {
-        return deleteConfig.equals("soft") ? true : false;
-    }
-
     private void setLicensePatterns (Properties properties) {
         setFreeLicensePattern(compilePattern(getFreeOnlyRegex()));
         setPublicLicensePattern(compilePattern(
@@ -310,22 +293,6 @@
         this.allOnlyRegex = allOnlyRegex;
     }
 
-    public boolean isSoftDeleteGroupMember () {
-        return isSoftDeleteGroupMember;
-    }
-
-    public void setSoftDeleteGroupMember (boolean isSoftDeleteGroupMember) {
-        this.isSoftDeleteGroupMember = isSoftDeleteGroupMember;
-    }
-
-    public boolean isSoftDeleteAutoGroup () {
-        return isSoftDeleteAutoGroup;
-    }
-
-    public void setSoftDeleteAutoGroup (boolean isSoftDeleteAutoGroup) {
-        this.isSoftDeleteAutoGroup = isSoftDeleteAutoGroup;
-    }
-
     public String getTestEmail () {
         return testEmail;
     }
diff --git a/src/main/java/de/ids_mannheim/korap/constant/GroupMemberStatus.java b/src/main/java/de/ids_mannheim/korap/constant/GroupMemberStatus.java
index 445e31e..87f3d04 100644
--- a/src/main/java/de/ids_mannheim/korap/constant/GroupMemberStatus.java
+++ b/src/main/java/de/ids_mannheim/korap/constant/GroupMemberStatus.java
@@ -10,8 +10,5 @@
     ACTIVE,
     // membership invitation was sent and has not been accepted 
     // or rejected yet
-    PENDING,
-    // either membership invitation was rejected or the member was 
-    // deleted by a user-group admin
-    DELETED;
+    PENDING;
 }
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 38ab977..3d99612 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -195,9 +195,7 @@
                 criteriaBuilder.equal(root.get(UserGroup_.status),
                         UserGroupStatus.ACTIVE),
                 criteriaBuilder.equal(members.get(UserGroupMember_.userId),
-                        userId),
-                criteriaBuilder.notEqual(members.get(UserGroupMember_.status),
-                        GroupMemberStatus.DELETED));
+                        userId));
         // criteriaBuilder.equal(members.get(UserGroupMember_.status),
         // GroupMemberStatus.ACTIVE));
 
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 d7b57bd..4909019 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
@@ -53,8 +53,8 @@
         entityManager.merge(member);
     }
 
-    public void deleteMember (UserGroupMember member, String deletedBy,
-            boolean isSoftDelete) throws KustvaktException {
+    public void deleteMember (UserGroupMember member, String deletedBy)
+            throws KustvaktException {
         ParameterChecker.checkObjectValue(member, "UserGroupMember");
         ParameterChecker.checkStringValue(deletedBy, "deletedBy");
 
@@ -62,16 +62,8 @@
             member = entityManager.merge(member);
         }
 
-        if (isSoftDelete) {
-            member.setStatus(GroupMemberStatus.DELETED);
-            member.setDeletedBy(deletedBy);
-            member.setRoles(new HashSet<>());
-            entityManager.persist(member);
-        }
-        else {
-            member.setRoles(new HashSet<>());
-            entityManager.remove(member);
-        }
+        member.setRoles(new HashSet<>());
+        entityManager.remove(member);
     }
 
     public UserGroupMember retrieveMemberById (String userId, int groupId)
@@ -138,14 +130,9 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     public List<UserGroupMember> retrieveMemberByGroupId (int groupId)
             throws KustvaktException {
-        return retrieveMemberByGroupId(groupId, false);
-    }
-
-    @SuppressWarnings("unchecked")
-    public List<UserGroupMember> retrieveMemberByGroupId (int groupId,
-            boolean isAdmin) throws KustvaktException {
         CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
         CriteriaQuery<UserGroupMember> query = criteriaBuilder
                 .createQuery(UserGroupMember.class);
@@ -155,12 +142,6 @@
         Predicate predicate = criteriaBuilder.and(criteriaBuilder
                 .equal(root.get(UserGroupMember_.group), groupId));
 
-        if (!isAdmin) {
-            predicate = criteriaBuilder.and(predicate,
-                    criteriaBuilder.notEqual(root.get(UserGroupMember_.status),
-                            GroupMemberStatus.DELETED));
-        }
-
         query.select(root);
         query.where(predicate);
         Query q = entityManager.createQuery(query);
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 ccb65ad..7456ee4 100644
--- a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -162,8 +162,7 @@
         List<UserGroupMember> members;
         UserGroupDto groupDto;
         for (UserGroup group : userGroups) {
-            members = groupMemberDao.retrieveMemberByGroupId(group.getId(),
-                    true);
+            members = groupMemberDao.retrieveMemberByGroupId(group.getId());
             groupDto = converter.createUserGroupDto(group, members, null, null);
             dtos.add(groupDto);
         }
@@ -370,11 +369,6 @@
                 || existingStatus.equals(status)) {
             return existingStatus;
         }
-        else if (existingStatus.equals(GroupMemberStatus.DELETED)) {
-            // hard delete, not customizable
-            doDeleteMember(username, groupId, "system", false);
-        }
-
         return null;
     }
 
@@ -445,13 +439,7 @@
         UserGroupMember member = groupMemberDao.retrieveMemberById(username,
                 userGroup.getId());
         GroupMemberStatus status = member.getStatus();
-        if (status.equals(GroupMemberStatus.DELETED)) {
-            throw new KustvaktException(StatusCodes.GROUP_MEMBER_DELETED,
-                    username + " has already been deleted from the group "
-                            + userGroup.getName(),
-                    username, userGroup.getName());
-        }
-        else if (member.getStatus().equals(GroupMemberStatus.ACTIVE)) {
+        if (member.getStatus().equals(GroupMemberStatus.ACTIVE)) {
             throw new KustvaktException(StatusCodes.GROUP_MEMBER_EXISTS,
                     "Username " + username + " with status " + status
                             + " exists in the user-group "
@@ -506,9 +494,9 @@
         else if (memberId.equals(deletedBy)
                 || isUserGroupAdmin(deletedBy, userGroup)
                 || adminDao.isAdmin(deletedBy)) {
-            // soft delete
-            doDeleteMember(memberId, userGroup.getId(), deletedBy,
-                    config.isSoftDeleteGroupMember());
+            UserGroupMember member = groupMemberDao.retrieveMemberById(memberId,
+                    userGroup.getId());
+            groupMemberDao.deleteMember(member, deletedBy);
         }
         else {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
@@ -516,39 +504,6 @@
         }
     }
 
-    /**
-     * Updates the {@link GroupMemberStatus} of a member to
-     * {@link GroupMemberStatus#DELETED}
-     * 
-     * @param userId
-     *            user to be deleted
-     * @param groupId
-     *            user-group id
-     * @param deletedBy
-     *            user that issue the delete
-     * @param isSoftDelete
-     *            true if database entry is to be deleted
-     *            permanently, false otherwise
-     * @throws KustvaktException
-     */
-    private void doDeleteMember (String username, int groupId, String deletedBy,
-            boolean isSoftDelete) throws KustvaktException {
-
-        UserGroup group = userGroupDao.retrieveGroupById(groupId);
-
-        UserGroupMember member = groupMemberDao.retrieveMemberById(username,
-                groupId);
-        GroupMemberStatus status = member.getStatus();
-        if (isSoftDelete && status.equals(GroupMemberStatus.DELETED)) {
-            throw new KustvaktException(StatusCodes.GROUP_MEMBER_DELETED,
-                    username + " has already been deleted from the group "
-                            + group.getName(),
-                    username, group.getName());
-        }
-
-        groupMemberDao.deleteMember(member, deletedBy, isSoftDelete);
-    }
-
     public UserGroupDto searchByName (String groupName)
             throws KustvaktException {
         UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, true);
diff --git a/src/test/java/de/ids_mannheim/korap/dao/DaoTestBase.java b/src/test/java/de/ids_mannheim/korap/dao/DaoTestBase.java
index 8e32b02..c79bd0a 100644
--- a/src/test/java/de/ids_mannheim/korap/dao/DaoTestBase.java
+++ b/src/test/java/de/ids_mannheim/korap/dao/DaoTestBase.java
@@ -39,9 +39,6 @@
                 GroupMemberStatus.ACTIVE);
         userGroupService.addGroupMember("marlin", group, "dory",
                 GroupMemberStatus.PENDING);
-        userGroupService.addGroupMember("pearl", group, "dory",
-                GroupMemberStatus.DELETED);
-
         return group;
     }
     
diff --git a/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java b/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
index 067ee6a..f747a89 100644
--- a/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
+++ b/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
@@ -53,7 +53,7 @@
         // dory group
         List<UserGroupMember> members = userGroupDao
                 .retrieveGroupById(group.getId(), true).getMembers();
-        assertEquals(4, members.size());
+        assertEquals(3, members.size());
 
         UserGroupMember m = members.get(1);
         Set<Role> roles = m.getRoles();
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerTest.java
index 4806241..8562fd3 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerTest.java
@@ -16,7 +16,6 @@
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Entity;
 import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.Response.Status;
 
@@ -27,9 +26,6 @@
 
     private String username = "UserGroupControllerTest";
 
-    private String admin = "admin";
-
-    
     @Test
     public void testCreateGroupEmptyDescription ()
             throws ProcessingException, KustvaktException {
@@ -196,11 +192,11 @@
         String entity = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.GROUP_MEMBER_DELETED,
+        assertEquals(StatusCodes.GROUP_MEMBER_NOT_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "pearl has already been deleted from the group dory-group");
-        assertEquals(node.at("/errors/0/2").asText(), "[pearl, dory-group]");
+        assertEquals("pearl is not found in the group",
+                node.at("/errors/0/1").asText());
+        assertEquals("pearl",node.at("/errors/0/2").asText());
         
         deleteGroupByName(doryGroupName, "dory");
     }
@@ -208,30 +204,8 @@
     private void testDeleteGroup (String groupName, String username)
             throws ProcessingException, KustvaktException {
         deleteGroupByName(groupName, username);
-        Form f = new Form();
-        f.param("username", username);
-        f.param("status", "DELETED");
-        // EM: this is so complicated because the group retrieval are not allowed
-        // for delete groups
-        // check group
-        Response response = target().path(API_VERSION).path("admin").path("group")
-                .path("list").request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.CONTENT_TYPE,
-                        MediaType.APPLICATION_FORM_URLENCODED)
-                .post(Entity.form(f));
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        for (int j = 0; j < node.size(); j++) {
-            JsonNode group = node.get(j);
-            // check group members
-            for (int i = 0; i < group.at("/0/members").size(); i++) {
-                assertEquals(GroupMemberStatus.DELETED.name(),
-                        group.at("/0/members/" + i + "/status").asText());
-            }
-        }
+        JsonNode node = listUserGroups(username);
+        assertEquals(0, node.size());
     }
 
     @Test
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupListTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupListTest.java
index 3344bf9..ac03ff5 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupListTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupListTest.java
@@ -43,7 +43,7 @@
         assertEquals(node.at("/0/owner").asText(), "dory");
         // group members are not allowed to see other members
         assertTrue(node.at("/0/members").isMissingNode());
-        System.out.println(node.toPrettyString());
+//        System.out.println(node.toPrettyString());
     }
     
     // marlin has 2 groups
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupSubscriptionTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupSubscriptionTest.java
index 5ffd446..8c12e55 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupSubscriptionTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupSubscriptionTest.java
@@ -32,8 +32,8 @@
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(StatusCodes.GROUP_MEMBER_NOT_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "bruce is not found in the group");
+        assertEquals("bruce is not found in the group",
+                node.at("/errors/0/1").asText());
         
         testSubscribeDeletedMember();
         deleteGroupByName(doryGroupName, "dory");
@@ -50,10 +50,8 @@
 
         String entity = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(StatusCodes.GROUP_MEMBER_DELETED,
+        assertEquals(StatusCodes.GROUP_MEMBER_NOT_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "pearl has already been deleted from the group dory-group");
         
         testUnsubscribeDeletedMember();
         testInviteDeletedMember("pearl", "dory");
@@ -143,8 +141,8 @@
         assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
         assertEquals(StatusCodes.NO_RESOURCE_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "Group non-existent is not found");
+        assertEquals("Group non-existent is not found",
+                node.at("/errors/0/1").asText());
     }
 
     @Test
@@ -210,11 +208,8 @@
         String entity = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.GROUP_MEMBER_DELETED,
+        assertEquals(StatusCodes.GROUP_MEMBER_NOT_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "pearl has already been deleted from the group dory-group");
-        assertEquals(node.at("/errors/0/2").asText(), "[pearl, dory-group]");
     }
 
 
@@ -243,8 +238,8 @@
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(StatusCodes.GROUP_MEMBER_NOT_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "bruce is not found in the group");
+        assertEquals("bruce is not found in the group", 
+                node.at("/errors/0/1").asText());
         deleteGroupByName(doryGroupName, "dory");
     }
 
@@ -261,8 +256,8 @@
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(StatusCodes.NO_RESOURCE_FOUND,
                 node.at("/errors/0/0").asInt());
-        assertEquals(node.at("/errors/0/1").asText(),
-                "Group tralala-group is not found");
+        assertEquals("Group tralala-group is not found",
+                node.at("/errors/0/1").asText());
     }
 
 }