From 84ee72a5764e438334d65feaf1873666f7898ad5 Mon Sep 17 00:00:00 2001
From: Sonia Zorba <sonia.zorba@inaf.it>
Date: Wed, 14 Aug 2019 18:52:39 +0200
Subject: [PATCH] Refactoring and cleanup

---
 .../ia2/gms/controller/GroupsController.java  | 25 ++++----
 .../controller/GroupsTabResponseBuilder.java  | 44 +++++++++++++
 .../gms/controller/HomePageController.java    | 39 ++++++++++++
 .../ia2/gms/controller/MembersController.java | 26 ++++++--
 .../gms/controller/PermissionsController.java | 27 ++++++--
 .../gms/controller/WebServiceController.java  |  5 +-
 .../ia2/gms/model/GroupsModelRequest.java     | 39 ------------
 .../AddGroupRequest.java}                     |  4 +-
 .../model/{ => request}/AddMemberRequest.java |  4 +-
 .../{ => request}/AddMemberWsRequest.java     |  2 +-
 .../{ => request}/AddPermissionRequest.java   |  3 +-
 .../{ => request}/AddPermissionWsRequest.java |  3 +-
 .../model/{ => request}/MemberRequest.java    |  2 +-
 .../{ => request}/PaginatedModelRequest.java  |  2 +-
 .../{ => request}/RemoveMemberRequest.java    |  2 +-
 .../{ => request}/RenameGroupRequest.java     |  2 +-
 .../ia2/gms/model/request/TabRequest.java     | 17 +++++
 .../{ => response}/BaseModelResponse.java     |  2 +-
 .../GroupsTabResponse.java}                   | 25 ++------
 .../gms/model/response/HomePageResponse.java  | 14 +++++
 .../model/{ => response}/PaginatedData.java   |  2 +-
 .../ia2/gms/service/GroupsModelBuilder.java   | 62 -------------------
 .../ia2/gms/service/GroupsTreeBuilder.java    |  4 +-
 .../gms/controller/GroupsControllerTest.java  | 59 ++++++++++++------
 .../controller/HomePageControllerTest.java    | 50 +++++++++++++++
 .../gms/controller/MembersControllerTest.java |  2 +-
 .../controller/PermissionsControllerTest.java |  2 +-
 .../controller/WebServiceControllerTest.java  |  4 +-
 .../inaf/ia2/gms/model/PaginatedDataTest.java |  1 +
 .../NestedGroupsIntegrationTest.java          |  2 +-
 30 files changed, 291 insertions(+), 184 deletions(-)
 create mode 100644 gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java
 create mode 100644 gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java
 delete mode 100644 gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelRequest.java
 rename gms/src/main/java/it/inaf/ia2/gms/model/{CreateGroupRequest.java => request/AddGroupRequest.java} (83%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/AddMemberRequest.java (86%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/AddMemberWsRequest.java (91%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/AddPermissionRequest.java (90%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/AddPermissionWsRequest.java (90%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/MemberRequest.java (92%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/PaginatedModelRequest.java (93%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/RemoveMemberRequest.java (89%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => request}/RenameGroupRequest.java (91%)
 create mode 100644 gms/src/main/java/it/inaf/ia2/gms/model/request/TabRequest.java
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => response}/BaseModelResponse.java (89%)
 rename gms/src/main/java/it/inaf/ia2/gms/model/{GroupsModelResponse.java => response/GroupsTabResponse.java} (54%)
 create mode 100644 gms/src/main/java/it/inaf/ia2/gms/model/response/HomePageResponse.java
 rename gms/src/main/java/it/inaf/ia2/gms/model/{ => response}/PaginatedData.java (98%)
 delete mode 100644 gms/src/main/java/it/inaf/ia2/gms/service/GroupsModelBuilder.java
 create mode 100644 gms/src/test/java/it/inaf/ia2/gms/controller/HomePageControllerTest.java

diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java
index 0c894e2..82803df 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsController.java
@@ -2,16 +2,15 @@ package it.inaf.ia2.gms.controller;
 
 import it.inaf.ia2.gms.authn.SessionData;
 import it.inaf.ia2.gms.exception.UnauthorizedException;
-import it.inaf.ia2.gms.model.CreateGroupRequest;
+import it.inaf.ia2.gms.model.request.AddGroupRequest;
 import it.inaf.ia2.gms.model.GroupNode;
-import it.inaf.ia2.gms.model.GroupsModelRequest;
-import it.inaf.ia2.gms.model.GroupsModelResponse;
-import it.inaf.ia2.gms.model.PaginatedData;
-import it.inaf.ia2.gms.model.PaginatedModelRequest;
+import it.inaf.ia2.gms.model.request.TabRequest;
+import it.inaf.ia2.gms.model.response.PaginatedData;
+import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
 import it.inaf.ia2.gms.model.Permission;
-import it.inaf.ia2.gms.model.RenameGroupRequest;
+import it.inaf.ia2.gms.model.request.RenameGroupRequest;
+import it.inaf.ia2.gms.model.response.GroupsTabResponse;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
-import it.inaf.ia2.gms.service.GroupsModelBuilder;
 import it.inaf.ia2.gms.service.GroupsService;
 import it.inaf.ia2.gms.service.GroupsTreeBuilder;
 import it.inaf.ia2.gms.service.PermissionsService;
@@ -41,18 +40,18 @@ public class GroupsController {
     private GroupsService groupsService;
 
     @Autowired
-    private GroupsModelBuilder groupsModelService;
+    private GroupsTreeBuilder groupsTreeBuilder;
 
     @Autowired
-    private GroupsTreeBuilder groupsTreeBuilder;
+    private GroupsTabResponseBuilder groupsTabResponseBuilder;
 
     @GetMapping(value = "/groups", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
-    public GroupsModelResponse getGroupsModelResponse(@Valid GroupsModelRequest groupsModelRequest) {
-        return groupsModelService.getGroupsModel(groupsModelRequest, session.getUserId());
+    public ResponseEntity<GroupsTabResponse> getGroupsTab(@Valid TabRequest request) {
+        return ResponseEntity.ok(groupsTabResponseBuilder.getGroupsTab(request));
     }
 
     @PostMapping(value = "/group", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
-    public ResponseEntity<PaginatedData<GroupNode>> createGroup(@Valid @RequestBody CreateGroupRequest request) {
+    public ResponseEntity<PaginatedData<GroupNode>> createGroup(@Valid @RequestBody AddGroupRequest request) {
 
         GroupEntity parent = groupsService.getGroupById(request.getParentGroupId());
 
@@ -60,7 +59,7 @@ public class GroupsController {
             throw new UnauthorizedException("Missing admin permission");
         }
 
-        GroupEntity newGroup = groupsService.addGroup(parent, request.getNewGroupName());
+        groupsService.addGroup(parent, request.getNewGroupName());
 
         PaginatedData<GroupNode> groupsPanel = getGroupsPanel(request.getParentGroupId(), request);
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java
new file mode 100644
index 0000000..420fe2a
--- /dev/null
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/GroupsTabResponseBuilder.java
@@ -0,0 +1,44 @@
+package it.inaf.ia2.gms.controller;
+
+import it.inaf.ia2.gms.authn.SessionData;
+import it.inaf.ia2.gms.model.Permission;
+import it.inaf.ia2.gms.model.request.TabRequest;
+import it.inaf.ia2.gms.model.response.GroupsTabResponse;
+import it.inaf.ia2.gms.persistence.model.GroupEntity;
+import it.inaf.ia2.gms.service.GroupsService;
+import it.inaf.ia2.gms.service.GroupsTreeBuilder;
+import it.inaf.ia2.gms.service.PermissionsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GroupsTabResponseBuilder {
+
+    @Autowired
+    private SessionData session;
+
+    @Autowired
+    private PermissionsService permissionsService;
+
+    @Autowired
+    private GroupsService groupsService;
+
+    @Autowired
+    private GroupsTreeBuilder groupsTreeBuilder;
+
+    public GroupsTabResponse getGroupsTab(TabRequest request) {
+
+        GroupEntity group = groupsService.getGroupById(request.getGroupId());
+
+        GroupsTabResponse response = new GroupsTabResponse();
+
+        response.setBreadcrumbs(groupsService.getBreadcrumbs(group.getPath()));
+
+        Permission currentNodePermissions = permissionsService.getUserPermissionForGroup(group, session.getUserId());
+        response.setPermission(currentNodePermissions);
+
+        response.setGroupsPanel(groupsTreeBuilder.listSubGroups(group.getId(), session.getUserId(), request));
+
+        return response;
+    }
+}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java
new file mode 100644
index 0000000..6ad84e2
--- /dev/null
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java
@@ -0,0 +1,39 @@
+package it.inaf.ia2.gms.controller;
+
+import it.inaf.ia2.gms.authn.SessionData;
+import it.inaf.ia2.gms.model.request.TabRequest;
+import it.inaf.ia2.gms.model.response.GroupsTabResponse;
+import it.inaf.ia2.gms.model.response.HomePageResponse;
+import javax.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Controller
+public class HomePageController {
+
+    @Autowired
+    private SessionData session;
+
+    @Autowired
+    private GroupsTabResponseBuilder groupsTabResponseBuilder;
+
+    @ResponseBody
+    @GetMapping(value = "/home", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public ResponseEntity<HomePageResponse> getMainPage(@Valid TabRequest request) {
+
+        HomePageResponse response = new HomePageResponse();
+
+        response.setUser(session.getUserId());
+
+        GroupsTabResponse groupsTabResponse = groupsTabResponseBuilder.getGroupsTab(request);
+        response.setBreadcrumbs(groupsTabResponse.getBreadcrumbs());
+        response.setGroupsPanel(groupsTabResponse.getGroupsPanel());
+        response.setPermission(groupsTabResponse.getPermission());
+
+        return ResponseEntity.ok(response);
+    }
+}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java
index d6069b1..df39a43 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/MembersController.java
@@ -2,12 +2,13 @@ package it.inaf.ia2.gms.controller;
 
 import it.inaf.ia2.gms.authn.SessionData;
 import it.inaf.ia2.gms.exception.UnauthorizedException;
-import it.inaf.ia2.gms.model.AddMemberRequest;
-import it.inaf.ia2.gms.model.MemberRequest;
-import it.inaf.ia2.gms.model.PaginatedData;
+import it.inaf.ia2.gms.model.request.AddMemberRequest;
+import it.inaf.ia2.gms.model.request.MemberRequest;
+import it.inaf.ia2.gms.model.response.PaginatedData;
 import it.inaf.ia2.gms.model.Permission;
 import it.inaf.ia2.gms.model.RapUser;
-import it.inaf.ia2.gms.model.RemoveMemberRequest;
+import it.inaf.ia2.gms.model.request.RemoveMemberRequest;
+import it.inaf.ia2.gms.model.request.TabRequest;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.service.GroupsService;
 import it.inaf.ia2.gms.service.MembersService;
@@ -19,6 +20,7 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
@@ -38,6 +40,22 @@ public class MembersController {
     @Autowired
     private MembersService membersService;
 
+    @GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public ResponseEntity<PaginatedData<RapUser>> getMembersTab(TabRequest request) {
+
+        GroupEntity group = groupsService.getGroupById(request.getGroupId());
+        Permission currentNodePermissions = permissionsService.getUserPermissionForGroup(group, session.getUserId());
+
+        if (currentNodePermissions == Permission.TRAVERSE) {
+            throw new UnauthorizedException("You have not the permission to view members");
+        }
+
+        List<RapUser> members = membersService.getMembers(group.getId());
+        PaginatedData<RapUser> membersPanel = new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize());
+
+        return ResponseEntity.ok(membersPanel);
+    }
+
     @PostMapping(value = "/member", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
     public ResponseEntity<PaginatedData<RapUser>> addMember(@Valid @RequestBody AddMemberRequest request) {
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java
index cd9ba1e..8d011d6 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/PermissionsController.java
@@ -2,12 +2,13 @@ package it.inaf.ia2.gms.controller;
 
 import it.inaf.ia2.gms.authn.SessionData;
 import it.inaf.ia2.gms.exception.UnauthorizedException;
-import it.inaf.ia2.gms.model.AddPermissionRequest;
-import it.inaf.ia2.gms.model.MemberRequest;
-import it.inaf.ia2.gms.model.PaginatedData;
-import it.inaf.ia2.gms.model.PaginatedModelRequest;
+import it.inaf.ia2.gms.model.request.AddPermissionRequest;
+import it.inaf.ia2.gms.model.request.MemberRequest;
+import it.inaf.ia2.gms.model.response.PaginatedData;
+import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
 import it.inaf.ia2.gms.model.Permission;
 import it.inaf.ia2.gms.model.UserPermission;
+import it.inaf.ia2.gms.model.request.TabRequest;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.service.GroupsService;
 import it.inaf.ia2.gms.service.PermissionsService;
@@ -38,7 +39,23 @@ public class PermissionsController {
     @Autowired
     private PermissionsService permissionsService;
 
-    @GetMapping(value = "/permission")
+    @GetMapping(value = "/permissions", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public ResponseEntity<PaginatedData<UserPermission>> getPermissionsTab(TabRequest request) {
+
+        GroupEntity group = groupsService.getGroupById(request.getGroupId());
+        Permission currentNodePermissions = permissionsService.getUserPermissionForGroup(group, session.getUserId());
+
+        if (currentNodePermissions != Permission.ADMIN) {
+            throw new UnauthorizedException("Only administrators can see the permissions");
+        }
+
+        List<UserPermission> permissions = permissionsService.getAllPermissions(group);
+        PaginatedData<UserPermission> permissionsPanel = new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize());
+
+        return ResponseEntity.ok(permissionsPanel);
+    }
+
+    @GetMapping(value = "/permission", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
     public ResponseEntity<Map<String, Permission>> getUserPermission(@RequestParam("groupId") String groupId, @RequestParam("userId") String userId) {
 
         GroupEntity group = groupsService.getGroupById(groupId);
diff --git a/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java b/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java
index b57df94..2992f79 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/controller/WebServiceController.java
@@ -1,9 +1,8 @@
 package it.inaf.ia2.gms.controller;
 
 import it.inaf.ia2.gms.exception.BadRequestException;
-import it.inaf.ia2.gms.model.AddMemberWsRequest;
-import it.inaf.ia2.gms.model.AddPermissionWsRequest;
-import it.inaf.ia2.gms.model.Permission;
+import it.inaf.ia2.gms.model.request.AddMemberWsRequest;
+import it.inaf.ia2.gms.model.request.AddPermissionWsRequest;
 import it.inaf.ia2.gms.model.PrepareToJoinRequest;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.persistence.model.MembershipEntity;
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelRequest.java
deleted file mode 100644
index 5c7a393..0000000
--- a/gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelRequest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package it.inaf.ia2.gms.model;
-
-import javax.validation.constraints.NotNull;
-
-public class GroupsModelRequest extends PaginatedModelRequest {
-
-    @NotNull
-    private String groupId;
-
-    @NotNull
-    private String tab;
-
-    @NotNull
-    private String page;
-
-    public String getGroupId() {
-        return groupId;
-    }
-
-    public void setGroupId(String groupId) {
-        this.groupId = groupId;
-    }
-
-    public String getTab() {
-        return tab;
-    }
-
-    public void setTab(String tab) {
-        this.tab = tab;
-    }
-
-    public String getPage() {
-        return page;
-    }
-
-    public void setPage(String page) {
-        this.page = page;
-    }
-}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/CreateGroupRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddGroupRequest.java
similarity index 83%
rename from gms/src/main/java/it/inaf/ia2/gms/model/CreateGroupRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/AddGroupRequest.java
index d13ab80..3aeeb7f 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/CreateGroupRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddGroupRequest.java
@@ -1,8 +1,8 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 import javax.validation.constraints.NotEmpty;
 
-public class CreateGroupRequest extends PaginatedModelRequest {
+public class AddGroupRequest extends PaginatedModelRequest {
 
     @NotEmpty
     private String parentGroupId;
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberRequest.java
similarity index 86%
rename from gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberRequest.java
index 6f55c0a..14d24ed 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberRequest.java
@@ -1,4 +1,6 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
+
+import it.inaf.ia2.gms.model.Permission;
 
 public class AddMemberRequest extends MemberRequest {
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberWsRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberWsRequest.java
similarity index 91%
rename from gms/src/main/java/it/inaf/ia2/gms/model/AddMemberWsRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberWsRequest.java
index cf69804..7266739 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/AddMemberWsRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddMemberWsRequest.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 import java.util.List;
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionRequest.java
similarity index 90%
rename from gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionRequest.java
index e4b2037..c10ae5f 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionRequest.java
@@ -1,5 +1,6 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
+import it.inaf.ia2.gms.model.Permission;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionWsRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionWsRequest.java
similarity index 90%
rename from gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionWsRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionWsRequest.java
index 6e45d07..e8a4a17 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/AddPermissionWsRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/AddPermissionWsRequest.java
@@ -1,5 +1,6 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
+import it.inaf.ia2.gms.model.Permission;
 import java.util.List;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/MemberRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/MemberRequest.java
similarity index 92%
rename from gms/src/main/java/it/inaf/ia2/gms/model/MemberRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/MemberRequest.java
index 20d4873..de6d2c8 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/MemberRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/MemberRequest.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 import javax.validation.constraints.NotEmpty;
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/PaginatedModelRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/PaginatedModelRequest.java
similarity index 93%
rename from gms/src/main/java/it/inaf/ia2/gms/model/PaginatedModelRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/PaginatedModelRequest.java
index 371b90b..7910d69 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/PaginatedModelRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/PaginatedModelRequest.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 import javax.validation.constraints.Min;
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/RemoveMemberRequest.java
similarity index 89%
rename from gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/RemoveMemberRequest.java
index ff22515..820a2b8 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/RemoveMemberRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/RemoveMemberRequest.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 public class RemoveMemberRequest extends MemberRequest {
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/RenameGroupRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/RenameGroupRequest.java
similarity index 91%
rename from gms/src/main/java/it/inaf/ia2/gms/model/RenameGroupRequest.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/request/RenameGroupRequest.java
index 90feff7..1112b44 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/RenameGroupRequest.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/RenameGroupRequest.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.request;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/request/TabRequest.java b/gms/src/main/java/it/inaf/ia2/gms/model/request/TabRequest.java
new file mode 100644
index 0000000..e2d913b
--- /dev/null
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/request/TabRequest.java
@@ -0,0 +1,17 @@
+package it.inaf.ia2.gms.model.request;
+
+import javax.validation.constraints.NotNull;
+
+public class TabRequest extends PaginatedModelRequest {
+
+    @NotNull
+    private String groupId;
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/BaseModelResponse.java b/gms/src/main/java/it/inaf/ia2/gms/model/response/BaseModelResponse.java
similarity index 89%
rename from gms/src/main/java/it/inaf/ia2/gms/model/BaseModelResponse.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/response/BaseModelResponse.java
index b8999c5..1988d52 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/BaseModelResponse.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/response/BaseModelResponse.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.response;
 
 public abstract class BaseModelResponse {
 
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelResponse.java b/gms/src/main/java/it/inaf/ia2/gms/model/response/GroupsTabResponse.java
similarity index 54%
rename from gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelResponse.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/response/GroupsTabResponse.java
index 25cef04..4df4cb5 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/GroupsModelResponse.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/response/GroupsTabResponse.java
@@ -1,13 +1,14 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.response;
 
+import it.inaf.ia2.gms.model.GroupBreadcrumb;
+import it.inaf.ia2.gms.model.GroupNode;
+import it.inaf.ia2.gms.model.Permission;
 import java.util.List;
 
-public class GroupsModelResponse extends BaseModelResponse {
+public class GroupsTabResponse {
 
     private List<GroupBreadcrumb> breadcrumbs;
     private PaginatedData<GroupNode> groupsPanel;
-    private PaginatedData<RapUser> membersPanel;
-    private PaginatedData<UserPermission> permissionsPanel;
     // current group permissions
     private Permission permission;
 
@@ -27,22 +28,6 @@ public class GroupsModelResponse extends BaseModelResponse {
         this.groupsPanel = groupsPanel;
     }
 
-    public PaginatedData<RapUser> getMembersPanel() {
-        return membersPanel;
-    }
-
-    public void setMembersPanel(PaginatedData<RapUser> membersPanel) {
-        this.membersPanel = membersPanel;
-    }
-
-    public PaginatedData<UserPermission> getPermissionsPanel() {
-        return permissionsPanel;
-    }
-
-    public void setPermissionsPanel(PaginatedData<UserPermission> permissionsPanel) {
-        this.permissionsPanel = permissionsPanel;
-    }
-
     public Permission getPermission() {
         return permission;
     }
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/response/HomePageResponse.java b/gms/src/main/java/it/inaf/ia2/gms/model/response/HomePageResponse.java
new file mode 100644
index 0000000..418e465
--- /dev/null
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/response/HomePageResponse.java
@@ -0,0 +1,14 @@
+package it.inaf.ia2.gms.model.response;
+
+public class HomePageResponse extends GroupsTabResponse {
+
+    private String user;
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/model/PaginatedData.java b/gms/src/main/java/it/inaf/ia2/gms/model/response/PaginatedData.java
similarity index 98%
rename from gms/src/main/java/it/inaf/ia2/gms/model/PaginatedData.java
rename to gms/src/main/java/it/inaf/ia2/gms/model/response/PaginatedData.java
index 0e61eb1..78f917a 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/model/PaginatedData.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/model/response/PaginatedData.java
@@ -1,4 +1,4 @@
-package it.inaf.ia2.gms.model;
+package it.inaf.ia2.gms.model.response;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/GroupsModelBuilder.java b/gms/src/main/java/it/inaf/ia2/gms/service/GroupsModelBuilder.java
deleted file mode 100644
index a057747..0000000
--- a/gms/src/main/java/it/inaf/ia2/gms/service/GroupsModelBuilder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package it.inaf.ia2.gms.service;
-
-import it.inaf.ia2.gms.model.GroupsModelRequest;
-import it.inaf.ia2.gms.model.GroupsModelResponse;
-import it.inaf.ia2.gms.model.PaginatedData;
-import it.inaf.ia2.gms.model.Permission;
-import it.inaf.ia2.gms.model.RapUser;
-import it.inaf.ia2.gms.model.UserPermission;
-import it.inaf.ia2.gms.persistence.model.GroupEntity;
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class GroupsModelBuilder {
-
-    @Autowired
-    private GroupsService groupsService;
-
-    @Autowired
-    private GroupsTreeBuilder groupsTreeBuilder;
-
-    @Autowired
-    private MembersService membersService;
-
-    @Autowired
-    private PermissionsService permissionsService;
-
-    public GroupsModelResponse getGroupsModel(GroupsModelRequest request, String userId) {
-
-        GroupEntity group = groupsService.getGroupById(request.getGroupId());
-
-        GroupsModelResponse response = new GroupsModelResponse();
-
-        response.setPage("groups");
-
-        response.setBreadcrumbs(groupsService.getBreadcrumbs(group.getPath()));
-
-        Permission currentNodePermissions = permissionsService.getUserPermissionForGroup(group, userId);
-        response.setPermission(currentNodePermissions);
-
-        switch (request.getTab()) {
-            case "groups":
-                response.setGroupsPanel(groupsTreeBuilder.listSubGroups(group.getId(), userId, request));
-                break;
-            case "members":
-                if (currentNodePermissions != Permission.TRAVERSE) {
-                    List<RapUser> members = membersService.getMembers(group.getId());
-                    response.setMembersPanel(new PaginatedData<>(members, request.getPaginatorPage(), request.getPaginatorPageSize()));
-                }
-                break;
-            case "permissions":
-                if (currentNodePermissions == Permission.ADMIN) {
-                    List<UserPermission> permissions = permissionsService.getAllPermissions(group);
-                    response.setPermissionsPanel(new PaginatedData<>(permissions, request.getPaginatorPage(), request.getPaginatorPageSize()));
-                }
-                break;
-        }
-
-        return response;
-    }
-}
diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/GroupsTreeBuilder.java b/gms/src/main/java/it/inaf/ia2/gms/service/GroupsTreeBuilder.java
index 280d5ee..665e90b 100644
--- a/gms/src/main/java/it/inaf/ia2/gms/service/GroupsTreeBuilder.java
+++ b/gms/src/main/java/it/inaf/ia2/gms/service/GroupsTreeBuilder.java
@@ -2,8 +2,8 @@ package it.inaf.ia2.gms.service;
 
 import it.inaf.ia2.gms.exception.BadRequestException;
 import it.inaf.ia2.gms.model.GroupNode;
-import it.inaf.ia2.gms.model.PaginatedData;
-import it.inaf.ia2.gms.model.PaginatedModelRequest;
+import it.inaf.ia2.gms.model.response.PaginatedData;
+import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
 import it.inaf.ia2.gms.persistence.GroupsDAO;
 import it.inaf.ia2.gms.persistence.PermissionsDAO;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java
index 37e7b92..f1acf43 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/controller/GroupsControllerTest.java
@@ -1,23 +1,30 @@
 package it.inaf.ia2.gms.controller;
 
 import it.inaf.ia2.gms.authn.SessionData;
-import it.inaf.ia2.gms.model.GroupsModelRequest;
-import it.inaf.ia2.gms.model.GroupsModelResponse;
-import it.inaf.ia2.gms.service.GroupsModelBuilder;
-import static org.junit.Assert.assertEquals;
+import it.inaf.ia2.gms.model.GroupNode;
+import it.inaf.ia2.gms.model.Permission;
+import it.inaf.ia2.gms.model.response.PaginatedData;
+import it.inaf.ia2.gms.persistence.model.GroupEntity;
+import it.inaf.ia2.gms.service.GroupsService;
+import it.inaf.ia2.gms.service.GroupsTreeBuilder;
+import it.inaf.ia2.gms.service.PermissionsService;
+import java.util.ArrayList;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.springframework.test.web.servlet.MockMvc;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -27,7 +34,17 @@ public class GroupsControllerTest {
     private SessionData session;
 
     @Mock
-    private GroupsModelBuilder groupsModelService;
+    private GroupsService groupsService;
+
+    @Mock
+    private PermissionsService permissionsService;
+
+    @Mock
+    private GroupsTreeBuilder groupsTreeBuilder;
+
+    @Spy
+    @InjectMocks
+    private GroupsTabResponseBuilder groupsTabResponseBuilder;
 
     @InjectMocks
     private GroupsController controller;
@@ -42,21 +59,25 @@ public class GroupsControllerTest {
     @Test
     public void testGetGroups() throws Exception {
 
-        GroupsModelResponse response = new GroupsModelResponse();
+        when(session.getUserId()).thenReturn("admin_id");
+
+        GroupEntity root = new GroupEntity();
+        root.setId("ROOT");
+        root.setName("ROOT");
+        root.setPath("");
 
-        when(groupsModelService.getGroupsModel(any(), any()))
-                .thenReturn(response);
+        when(groupsService.getGroupById(eq("ROOT"))).thenReturn(root);
 
-        mockMvc.perform(get("/groups?groupId=ROOT&tab=groups&paginatorPageSize=20&paginatorPage=1&page=main"))
-                .andExpect(status().isOk());
+        when(permissionsService.getUserPermissionForGroup(eq(root), eq("admin_id")))
+                .thenReturn(Permission.ADMIN);
 
-        ArgumentCaptor<GroupsModelRequest> requestCaptor = ArgumentCaptor.forClass(GroupsModelRequest.class);
-        verify(groupsModelService).getGroupsModel(requestCaptor.capture(), any());
-        GroupsModelRequest request = requestCaptor.getValue();
+        PaginatedData<GroupNode> groupsPanel = new PaginatedData<>(new ArrayList<>(), 1, 10);
+        when(groupsTreeBuilder.listSubGroups(eq("ROOT"), eq("admin_id"), any())).thenReturn(groupsPanel);
 
-        assertEquals("ROOT", request.getGroupId());
-        assertEquals("groups", request.getTab());
-        assertEquals(1, request.getPaginatorPage());
-        assertEquals(20, request.getPaginatorPageSize());
+        mockMvc.perform(get("/groups?groupId=ROOT&paginatorPageSize=20&paginatorPage=1"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.breadcrumbs", notNullValue()))
+                .andExpect(jsonPath("$.groupsPanel", notNullValue()))
+                .andExpect(jsonPath("$.permission", is("ADMIN")));
     }
 }
diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/HomePageControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/HomePageControllerTest.java
new file mode 100644
index 0000000..6f74fae
--- /dev/null
+++ b/gms/src/test/java/it/inaf/ia2/gms/controller/HomePageControllerTest.java
@@ -0,0 +1,50 @@
+package it.inaf.ia2.gms.controller;
+
+import it.inaf.ia2.gms.authn.SessionData;
+import it.inaf.ia2.gms.model.response.GroupsTabResponse;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.mockito.ArgumentMatchers.any;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import static org.mockito.Mockito.when;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(MockitoJUnitRunner.class)
+public class HomePageControllerTest {
+
+    @Mock
+    private SessionData session;
+
+    @Mock
+    private GroupsTabResponseBuilder groupsTabResponseBuilder;
+
+    @InjectMocks
+    private HomePageController controller;
+
+    private MockMvc mockMvc;
+
+    @Before
+    public void init() {
+        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
+    }
+
+    @Test
+    public void testGetHomePageModel() throws Exception {
+
+        when(session.getUserId()).thenReturn("admin_id");
+
+        when(groupsTabResponseBuilder.getGroupsTab(any())).thenReturn(new GroupsTabResponse());
+
+        mockMvc.perform(get("/home?groupId=ROOT&paginatorPageSize=20&paginatorPage=1"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.user", notNullValue()));
+    }
+}
diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java
index b18fc5a..968bf92 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/controller/MembersControllerTest.java
@@ -2,7 +2,7 @@ package it.inaf.ia2.gms.controller;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import it.inaf.ia2.gms.authn.SessionData;
-import it.inaf.ia2.gms.model.AddMemberRequest;
+import it.inaf.ia2.gms.model.request.AddMemberRequest;
 import it.inaf.ia2.gms.model.Permission;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.service.GroupsService;
diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java
index 4b635eb..b309bf1 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/controller/PermissionsControllerTest.java
@@ -3,7 +3,7 @@ package it.inaf.ia2.gms.controller;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import it.inaf.ia2.gms.authn.SessionData;
 import it.inaf.ia2.gms.model.Permission;
-import it.inaf.ia2.gms.model.AddPermissionRequest;
+import it.inaf.ia2.gms.model.request.AddPermissionRequest;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.service.GroupsService;
 import it.inaf.ia2.gms.service.PermissionsService;
diff --git a/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java b/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java
index 422b915..695bc77 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/controller/WebServiceControllerTest.java
@@ -1,8 +1,8 @@
 package it.inaf.ia2.gms.controller;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import it.inaf.ia2.gms.model.AddMemberWsRequest;
-import it.inaf.ia2.gms.model.AddPermissionWsRequest;
+import it.inaf.ia2.gms.model.request.AddMemberWsRequest;
+import it.inaf.ia2.gms.model.request.AddPermissionWsRequest;
 import it.inaf.ia2.gms.model.Permission;
 import it.inaf.ia2.gms.model.PrepareToJoinRequest;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
diff --git a/gms/src/test/java/it/inaf/ia2/gms/model/PaginatedDataTest.java b/gms/src/test/java/it/inaf/ia2/gms/model/PaginatedDataTest.java
index 79f2d9b..173f7e0 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/model/PaginatedDataTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/model/PaginatedDataTest.java
@@ -1,5 +1,6 @@
 package it.inaf.ia2.gms.model;
 
+import it.inaf.ia2.gms.model.response.PaginatedData;
 import java.util.ArrayList;
 import java.util.List;
 import static org.junit.Assert.assertEquals;
diff --git a/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java
index 0b79415..2ca372b 100644
--- a/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java
+++ b/gms/src/test/java/it/inaf/ia2/gms/persistence/NestedGroupsIntegrationTest.java
@@ -3,7 +3,7 @@ package it.inaf.ia2.gms.persistence;
 import it.inaf.ia2.gms.DataSourceConfig;
 import it.inaf.ia2.gms.service.GroupsService;
 import it.inaf.ia2.gms.model.GroupNode;
-import it.inaf.ia2.gms.model.PaginatedModelRequest;
+import it.inaf.ia2.gms.model.request.PaginatedModelRequest;
 import it.inaf.ia2.gms.model.Permission;
 import it.inaf.ia2.gms.persistence.model.GroupEntity;
 import it.inaf.ia2.gms.persistence.model.PermissionEntity;
-- 
GitLab