Replace add-member-role to add-admin-role web-service

Change-Id: Ic0f41978b2fbed160f887d47f854c0dff299cc83
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 8ec7c89..6c68c13 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
@@ -128,7 +128,7 @@
 
         Root<Role> role = query.from(Role.class);
         role.fetch("userGroup", JoinType.INNER);
-        role.fetch("query", JoinType.INNER);
+//        role.fetch("query", JoinType.INNER);
 //        role.fetch("userGroupMembers", JoinType.INNER);
         
         Expression<?> queryId = role.get("query").get("id");
diff --git a/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java b/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
index 8320c45..6b39bd4 100644
--- a/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
+++ b/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
@@ -64,7 +64,8 @@
     @Column(name = "query_language")
     private String queryLanguage;
 
-    @OneToMany(mappedBy = "query", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
+    @OneToMany(mappedBy = "query", fetch = FetchType.LAZY, 
+            cascade = CascadeType.REMOVE)
     private List<Role> roles;
 
     @Override
diff --git a/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java b/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
index 4638191..5c1e3fd 100644
--- a/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
+++ b/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
@@ -121,6 +121,7 @@
     public static final int GROUP_MEMBER_NOT_FOUND = 1604;
     public static final int INVITATION_EXPIRED = 1605;
     public static final int GROUP_DELETED = 1606;
+    public static final int GROUP_ADMIN_EXISTS = 1607;
 
     /**
      * 1800 Oauth2
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 a361716..084ed97 100644
--- a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -623,10 +623,8 @@
         }
     }
 
-    public void addMemberRoles (String username, String groupName,
-            String memberUsername, List<PredefinedRole> roleNames)
-            throws KustvaktException {
-
+    public void addAdminRole (String username, String groupName,
+            String memberUsername) throws KustvaktException {
         ParameterChecker.checkStringValue(username, "username");
         ParameterChecker.checkStringValue(groupName, "groupName");
         ParameterChecker.checkStringValue(memberUsername, "memberUsername");
@@ -637,7 +635,8 @@
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
                     "Usergroup has been deleted.");
         }
-        else if (isUserGroupAdmin(username, userGroup)
+
+        if (isUserGroupAdmin(username, userGroup)
                 || adminDao.isAdmin(username)) {
 
             UserGroupMember member = groupMemberDao
@@ -649,46 +648,39 @@
                         memberUsername, member.getStatus().name());
             }
 
-            Set<Role> existingRoles = member.getRoles();
-            for (PredefinedRole role : roleNames) {
-                boolean roleExists = false;
-                for (Role r :existingRoles) {
-                    if (r.getName().equals(role)) {
-                        roleExists = true;
-                        break;
-                    }
-                }
-                if (!roleExists) {
-                    if (role.equals(PredefinedRole.GROUP_ADMIN)) {
-                        Role r1 = new Role(role,PrivilegeType.READ_MEMBER, userGroup);
-                        roleDao.addRole(r1);
-                        existingRoles.add(r1);
-                        
-                        Role r2 = new Role(role,PrivilegeType.DELETE_MEMBER, userGroup);
-                        roleDao.addRole(r2);
-                        existingRoles.add(r2);
+            if (!isUserGroupAdmin(memberUsername, userGroup)) {
+                Set<Role> existingRoles = member.getRoles();
+                PredefinedRole role = PredefinedRole.GROUP_ADMIN;
 
-                        Role r3 = new Role(role,PrivilegeType.WRITE_MEMBER, userGroup);
-                        roleDao.addRole(r3);
-                        existingRoles.add(r3);
-                        
-                        Role r4 = new Role(role,PrivilegeType.SHARE_QUERY, userGroup);
-                        roleDao.addRole(r4);
-                        existingRoles.add(r4);
-                        
-                        Role r5 = new Role(role,PrivilegeType.DELETE_QUERY, userGroup);
-                        roleDao.addRole(r5);
-                        existingRoles.add(r5);
-                    }
-//                    else {
-//                        throw new KustvaktException(StatusCodes.NOT_ALLOWED,
-//                                "Adding role " + role.name()
-//                                        + " is not allowed.");
-//                    }
-                }
+                Role r1 = new Role(role, PrivilegeType.READ_MEMBER, userGroup);
+                roleDao.addRole(r1);
+                existingRoles.add(r1);
+
+                Role r2 = new Role(role, PrivilegeType.DELETE_MEMBER,
+                        userGroup);
+                roleDao.addRole(r2);
+                existingRoles.add(r2);
+
+                Role r3 = new Role(role, PrivilegeType.WRITE_MEMBER, userGroup);
+                roleDao.addRole(r3);
+                existingRoles.add(r3);
+
+                Role r4 = new Role(role, PrivilegeType.SHARE_QUERY, userGroup);
+                roleDao.addRole(r4);
+                existingRoles.add(r4);
+
+                Role r5 = new Role(role, PrivilegeType.DELETE_QUERY, userGroup);
+                roleDao.addRole(r5);
+                existingRoles.add(r5);
+
+                member.setRoles(existingRoles);
+                groupMemberDao.updateMember(member);
             }
-            member.setRoles(existingRoles);
-            groupMemberDao.updateMember(member);
+            else {
+                throw new KustvaktException(StatusCodes.GROUP_ADMIN_EXISTS,
+                        "Username " + memberUsername
+                         + " is already a group admin.");
+            }
 
         }
         else {
@@ -697,11 +689,6 @@
         }
     }
     
-    private void checkRole () {
-        // TODO Auto-generated method stub
-
-    }
-
     public void deleteMemberRoles (String username, String groupName,
             String memberUsername, List<PredefinedRole> rolesToBeDeleted)
             throws KustvaktException {
@@ -735,4 +722,5 @@
                     "Unauthorized operation for user: " + username, username);
         }
     }
+
 }
diff --git a/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
index c2893df..d11b0f7 100644
--- a/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
+++ b/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -258,33 +258,28 @@
         }
     }
 
-    /**
-     * Adds roles of an active member of a user-group. Only user-group
-     * admins and system admins are allowed.
+    /**Add group admin role to a member in a group 
      * 
      * @param securityContext
      * @param groupName
      *            a group name
      * @param memberUsername
      *            a username of a group member
-     * @param roleId
-     *            a role id or multiple role ids
-     * @return if successful, HTTP response status OK
+     * @return HTTP status 200, if successful 
      */
     @POST
-    @Path("@{groupName}/role/add")
+    @Path("@{groupName}/role/add/admin")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response addMemberRoles (@Context SecurityContext securityContext,
+    public Response addAdminRole (@Context SecurityContext securityContext,
             @PathParam("groupName") String groupName,
-            @FormParam("memberUsername") String memberUsername,
-            @FormParam("role") List<PredefinedRole> roles) {
+            @FormParam("memberUsername") String memberUsername) {
         TokenContext context = (TokenContext) securityContext
                 .getUserPrincipal();
         try {
             scopeService.verifyScope(context,
                     OAuth2Scope.ADD_USER_GROUP_MEMBER_ROLE);
-            service.addMemberRoles(context.getUsername(), groupName,
-                    memberUsername, roles);
+            service.addAdminRole(context.getUsername(), groupName,
+                    memberUsername);
             return Response.ok("SUCCESS").build();
         }
         catch (KustvaktException e) {
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerAdminTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerAdminTest.java
index b207fbc..138a562 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerAdminTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupControllerAdminTest.java
@@ -27,8 +27,6 @@
  */
 public class UserGroupControllerAdminTest extends UserGroupTestBase {
 
-    private String sysAdminUser = "admin";
-
     private String testUser = "group-admin";
 
     private JsonNode listGroup (String username)
@@ -128,7 +126,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .header(HttpHeaders.CONTENT_TYPE,
                         MediaType.APPLICATION_FORM_URLENCODED)
                 .post(Entity.form(f));
@@ -146,7 +144,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").get();
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         String entity = response.readEntity(String.class);
@@ -161,7 +159,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .header(HttpHeaders.CONTENT_TYPE,
                         MediaType.APPLICATION_FORM_URLENCODED)
                 .post(null);
@@ -197,28 +195,23 @@
         assertEquals(groupName, node.get("name").asText());
         testInviteMember(groupName);
         subscribe(groupName, "marlin");
-        testAddMemberRoles(groupName, "marlin");
+        testAddAdminRole(groupName, "marlin");
         testDeleteMemberRoles(groupName, "marlin");
         testDeleteMember(groupName);
         
         // delete group
-        deleteGroupByName(groupName, sysAdminUser);
+        deleteGroupByName(groupName, admin);
         // check group
         node = listGroup(testUser);
         assertEquals(0, node.size());
     }
 
 
-    private void testAddMemberRoles (String groupName, String memberUsername)
+    private void testAddAdminRole (String groupName, String memberUsername)
             throws ProcessingException, KustvaktException {
-        Form form = new Form();
-        form.param("memberUsername", memberUsername);
-        // USER_GROUP_ADMIN
-        form.param("role", PredefinedRole.GROUP_ADMIN.name());
-        // USER_GROUP_MEMBER
-        form.param("role", PredefinedRole.GROUP_MEMBER.name());
-        addMemberRole(groupName, sysAdminUser, form);
-
+        Response response = addAdminRole(groupName, memberUsername, admin);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        
         JsonNode node = retrieveGroup(groupName).at("/members");
         JsonNode member;
         for (int i = 0; i < node.size(); i++) {
@@ -241,7 +234,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "password"))
+                                        admin, "password"))
                 .post(Entity.form(form));
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         JsonNode node = retrieveGroup(groupName).at("/members");
@@ -262,7 +255,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").post(null);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         String entity = response.readEntity(String.class);
@@ -278,7 +271,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").delete();
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         // check group member
@@ -300,7 +293,7 @@
                 .header(Attributes.AUTHORIZATION,
                         HttpAuthorizationHandler
                                 .createBasicAuthorizationHeaderValue(
-                                        sysAdminUser, "pass"))
+                                        admin, "pass"))
                 .post(Entity.form(form));
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         // list group
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 44019ae..7363257 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
@@ -10,7 +10,6 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
-import de.ids_mannheim.korap.constant.PredefinedRole;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
@@ -242,11 +241,7 @@
         inviteMember(marlinGroupName, "marlin", "dory");
         subscribe(marlinGroupName, "dory");
         
-        Form form = new Form();
-        form.param("memberUsername", "dory");
-        form.param("role", PredefinedRole.GROUP_ADMIN.name());
-        form.param("role", PredefinedRole.QUERY_ACCESS.name());
-        addMemberRole(marlinGroupName, "marlin", form);
+        addAdminRole(marlinGroupName, "dory", "marlin");
         
         // dory is a group admin in marlin-group
         Response response = target().path(API_VERSION).path("group")
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupMemberTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupMemberTest.java
index 6d81711..1611da9 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupMemberTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupMemberTest.java
@@ -98,27 +98,28 @@
 //        assertEquals(node.at("/errors/0/2").asText(), "deleted-group");
     }
     
-    @Test
-    public void testAddMutipleRoles () throws KustvaktException {
-        createDoryGroup();
-        inviteMember(doryGroupName, "dory", "marlin");
-        subscribe(doryGroupName, "marlin");
-        JsonNode marlinGroup = listUserGroups("marlin");
-        int groupId = marlinGroup.at("/0/id").asInt();
-        
-        Form form = new Form();
-        form.param("memberUsername", "marlin");
-        form.param("role", PredefinedRole.GROUP_ADMIN.name());
-        form.param("role", PredefinedRole.QUERY_ACCESS.name());
-        addMemberRole(doryGroupName, "dory", form);
-        
-        UserGroupMember member = memberDao.retrieveMemberById("marlin",
-                groupId);
-        Set<Role> roles = member.getRoles();
-        assertEquals(6, roles.size());
-        
-        deleteGroupByName(doryGroupName, "dory");
-    }
+//    @Deprecated
+//    @Test
+//    public void testAddMutipleRoles () throws KustvaktException {
+//        createDoryGroup();
+//        inviteMember(doryGroupName, "dory", "marlin");
+//        subscribe(doryGroupName, "marlin");
+//        JsonNode marlinGroup = listUserGroups("marlin");
+//        int groupId = marlinGroup.at("/0/id").asInt();
+//        
+//        Form form = new Form();
+//        form.param("memberUsername", "marlin");
+//        form.param("role", PredefinedRole.GROUP_ADMIN.name());
+//        form.param("role", PredefinedRole.QUERY_ACCESS.name());
+//        addMemberRole(doryGroupName, "dory", form);
+//        
+//        UserGroupMember member = memberDao.retrieveMemberById("marlin",
+//                groupId);
+//        Set<Role> roles = member.getRoles();
+//        assertEquals(6, roles.size());
+//        
+//        deleteGroupByName(doryGroupName, "dory");
+//    }
     
     @Test
     public void testAddMemberRole () throws KustvaktException {
@@ -132,7 +133,8 @@
         Set<Role> roles = member.getRoles();
         assertEquals(1, roles.size());
         
-        addAdminRole(marlinGroupName, "dory", "marlin");
+        Response response = addAdminRole(marlinGroupName, "dory", "marlin");
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
         
         member = memberDao.retrieveMemberById("dory", groupId);
         roles = member.getRoles();
@@ -148,8 +150,14 @@
 
     private void testAddSameMemberRole (int groupId)
             throws ProcessingException, KustvaktException {
-        addAdminRole(marlinGroupName, "dory", "marlin");
-
+        Response response = addAdminRole(marlinGroupName, "dory", "marlin");
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+        
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(StatusCodes.GROUP_ADMIN_EXISTS,
+                node.at("/errors/0/0").asInt());
+        
         UserGroupMember member = memberDao.retrieveMemberById("dory", groupId);
         Set<Role> roles = member.getRoles();
         assertEquals(6, roles.size());
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 57c4227..2d675e3 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
@@ -116,7 +116,6 @@
         for (int i = 0; i < node.size(); i++) {
             member = node.get(i);
             if (deletedMemberName.equals(member.at("/userId").asText())) {
-                System.out.println(deletedMemberName);
                 assertEquals(0, node.at("/roles").size());
                 break;
             }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
index cc1c1b7..e5e46c4 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
@@ -23,6 +23,7 @@
 
     protected String doryGroupName = "dory-group";
     protected String marlinGroupName = "marlin-group";
+    protected String admin = "admin";
 
     protected Response createUserGroup (String groupName, String description,
             String username) throws ProcessingException, KustvaktException {
@@ -110,22 +111,19 @@
 //        assertEquals(Status.OK.getStatusCode(), response.getStatus());
     }
 
-    protected void addAdminRole (String groupName, String memberName,
+    protected Response addAdminRole (String groupName, String memberName,
             String addedBy) throws KustvaktException {
         Form form = new Form();
         form.param("memberUsername", memberName);
         form.param("role", PredefinedRole.GROUP_ADMIN.name());
-        addMemberRole(groupName, addedBy, form);
-    }
-    
-    protected void addMemberRole (String groupName, String addedBy,
-            Form form) throws KustvaktException {
+
         Response response = target().path(API_VERSION).path("group")
-                .path("@"+groupName).path("role").path("add").request()
+                .path("@" + groupName).path("role").path("add").path("admin")
+                .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(addedBy, "pass"))
                 .post(Entity.form(form));
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        return response;
     }
 
     protected Response deleteMember (String groupName, String memberName,
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
index 9898475..2107491 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
@@ -69,11 +69,8 @@
                 marlinGroupName);
         testResponseUnauthorized(response, "nemo");
 
-        Form form = new Form();
-        form.param("memberUsername", "nemo");
-        form.param("role", PredefinedRole.GROUP_ADMIN.name());
-        addMemberRole(marlinGroupName, "marlin", form);
-
+        addAdminRole(marlinGroupName, "nemo", "marlin");
+        
         response = shareVCByCreator("nemo", "nemo-vc", marlinGroupName);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());