diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/GmsClient.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/GmsClient.java index cfe275ab5d10e3994dd4164387b5bc3837a0e2ec..304df22c334f1d71a1cdc0225e27e69db1f1cbdb 100644 --- a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/GmsClient.java +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/GmsClient.java @@ -8,6 +8,7 @@ import it.inaf.ia2.gms.client.call.AddPermissionCall; import it.inaf.ia2.gms.client.call.CreateGroupCall; import it.inaf.ia2.gms.client.call.DeleteGroupCall; import it.inaf.ia2.gms.client.call.GetGroupPermissionsCall; +import it.inaf.ia2.gms.client.call.GetGroupStatusCall; import it.inaf.ia2.gms.client.call.GetMemberEmailAddresses; import it.inaf.ia2.gms.client.call.GetUserGroupsCall; import it.inaf.ia2.gms.client.call.GetUserPermissionsCall; @@ -153,7 +154,7 @@ public class GmsClient extends BaseClient { return new GetMemberEmailAddresses(this).getMemberEmailAddresses(groupId, permission); } - public Object call(HttpRequest groupsRequest, HttpResponse.BodyHandler<InputStream> ofInputStream) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public List<String[]> getStatus(String groupCompleteName) { + return new GetGroupStatusCall(this).getStatus(groupCompleteName); } } diff --git a/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupStatusCall.java b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupStatusCall.java new file mode 100644 index 0000000000000000000000000000000000000000..e81ea2dc5c2cdbe411d93b13142d7cb75d884654 --- /dev/null +++ b/gms-client/gms-client/src/main/java/it/inaf/ia2/gms/client/call/GetGroupStatusCall.java @@ -0,0 +1,27 @@ +package it.inaf.ia2.gms.client.call; + +import it.inaf.ia2.client.BaseCall; +import it.inaf.ia2.gms.client.GmsClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; + +public class GetGroupStatusCall extends BaseCall<GmsClient> { + + public GetGroupStatusCall(GmsClient client) { + super(client); + } + + public List<String[]> getStatus(String groupCompleteName) { + + String uri = "group/status?groupName=" + groupCompleteName; + + HttpRequest request = client.newRequest(uri) + .header("Accept", "application/json") + .GET() + .build(); + + return client.call(request, HttpResponse.BodyHandlers.ofInputStream(), 200, + in -> parseJsonList(in, String[].class)); + } +} diff --git a/gms-ui/src/components/GroupsBreadcrumb.vue b/gms-ui/src/components/GroupsBreadcrumb.vue index c638b20ee8b9f494da85e93d60ffe7f5c29cbf42..8911d9792d504016a7bb3ecf6d12f3cdd7de1926 100644 --- a/gms-ui/src/components/GroupsBreadcrumb.vue +++ b/gms-ui/src/components/GroupsBreadcrumb.vue @@ -6,7 +6,7 @@ <span v-if="group.active">{{group.groupName}}</span> </li> </ol> - <a v-if="currentGroup" :href="'group/status/' + currentGroup.groupId" :download="currentGroup.groupName + '.csv'" id="csv-status-download" title="Download CSV"> + <a v-if="currentGroup" :href="'group/status?groupId=' + currentGroup.groupId" :download="currentGroup.groupName + '.csv'" id="csv-status-download" title="Download CSV"> <font-awesome-icon icon="download"></font-awesome-icon> </a> </nav> 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 4bef932ad8648333180f7c8bf2b4a6ada9078879..d4c855a5bd5010e8727802b6dc43acde4f9b668d 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 @@ -1,5 +1,6 @@ package it.inaf.ia2.gms.controller; +import com.fasterxml.jackson.databind.ObjectMapper; import com.opencsv.CSVWriter; import it.inaf.ia2.gms.manager.GroupStatusManager; import it.inaf.ia2.gms.manager.GroupsManager; @@ -12,9 +13,12 @@ import it.inaf.ia2.gms.model.request.GroupsRequest; import it.inaf.ia2.gms.model.request.RenameGroupRequest; import it.inaf.ia2.gms.model.request.SearchFilterRequest; import it.inaf.ia2.gms.persistence.model.GroupEntity; +import it.inaf.ia2.gms.service.GroupNameService; import it.inaf.ia2.gms.service.GroupsTreeBuilder; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.util.List; +import java.util.Optional; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; @@ -28,11 +32,14 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GroupsController { + private static final ObjectMapper MAPPER = new ObjectMapper(); + @Autowired private HttpServletRequest servletRequest; @@ -48,6 +55,9 @@ public class GroupsController { @Autowired private GroupStatusManager groupStatusManager; + @Autowired + private GroupNameService groupNameService; + @GetMapping(value = "/groups", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<?> getGroupsTab(@Valid GroupsRequest request) { if (request.isOnlyPanel()) { @@ -93,15 +103,35 @@ public class GroupsController { return ResponseEntity.ok(groupsPanel); } - @GetMapping(value = "/group/status/{groupId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) - public void downloadStatus(@PathVariable("groupId") String groupId, HttpServletResponse response) throws Exception { + @GetMapping(value = "/group/status", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE}) + public void downloadStatus(@RequestParam(value = "groupId", required = false) String groupId, + @RequestParam(value = "groupName", required = false) String groupName, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + if (groupId == null && groupName == null) { + response.sendError(400, "Parameter groupId or groupName is required"); + return; + } + + if (groupId == null) { + GroupEntity group = groupNameService.getGroupFromNames(Optional.of(groupName)); + groupId = group.getId(); + } + + List<String[]> status = groupStatusManager.generateStatus(groupId); - try ( OutputStream out = response.getOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { + try ( OutputStream out = response.getOutputStream()) { - writer.writeNext(new String[]{"program", "email"}); + if ("application/json".equals(request.getHeader("Accept"))) { + MAPPER.writeValue(out, status); + } else { + try ( CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { + writer.writeNext(new String[]{"program", "email"}); - for (String[] row : groupStatusManager.generateStatus(groupId)) { - writer.writeNext(row); + for (String[] row : status) { + writer.writeNext(row); + } + } } } } diff --git a/gms/src/main/java/it/inaf/ia2/gms/manager/GroupStatusManager.java b/gms/src/main/java/it/inaf/ia2/gms/manager/GroupStatusManager.java index 98cbccdb1acfeb858bf7e2bedd85e5d8510133be..4570303ce6d229884e47c28f9881f49d28c150d3 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/manager/GroupStatusManager.java +++ b/gms/src/main/java/it/inaf/ia2/gms/manager/GroupStatusManager.java @@ -6,7 +6,6 @@ import it.inaf.ia2.gms.persistence.GroupsDAO; import it.inaf.ia2.gms.persistence.MembershipsDAO; import it.inaf.ia2.gms.persistence.model.GroupEntity; import it.inaf.ia2.gms.persistence.model.MembershipEntity; -import it.inaf.ia2.gms.service.GroupNameService; import it.inaf.ia2.gms.service.GroupsService; import it.inaf.ia2.rap.client.RapClient; import it.inaf.ia2.rap.data.RapUser; @@ -38,9 +37,6 @@ public class GroupStatusManager extends UserAwareComponent { @Autowired private MembershipsDAO membershipsDAO; - @Autowired - private GroupNameService groupNameService; - @Autowired private RapClient rapClient; @@ -50,14 +46,15 @@ public class GroupStatusManager extends UserAwareComponent { Permission groupPermission = permissionsManager.getCurrentUserPermission(parentGroup); - if (groupPermission != Permission.ADMIN) { - throw new UnauthorizedException("ADMIN permission is needed for performing this action"); + if (Permission.includes(Permission.VIEW_MEMBERS, groupPermission)) { + throw new UnauthorizedException("VIEW_MEMBERS permission is needed for performing this action"); } List<GroupEntity> groups = groupsDAO.getAllChildren(parentGroup.getPath()); groups.add(parentGroup); - List<String> names = groupNameService.getGroupsNames(groups); + Map<String, String> names = groupsDAO.getGroupCompleteNamesFromId(groups.stream() + .map(g -> g.getId()).collect(Collectors.toSet())); List<MembershipEntity> memberships = membershipsDAO.findByGroups(groups.stream() .map(g -> g.getId()).collect(Collectors.toList())); @@ -84,7 +81,7 @@ public class GroupStatusManager extends UserAwareComponent { for (int i = 0; i < groups.size(); i++) { GroupEntity group = groups.get(i); - String groupName = names.get(i); + String groupName = names.get(group.getId()); List<String> users = membersMap.get(group.getId()); if (users != null) { for (String userId : users) { diff --git a/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java b/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java index fc9061874c2974d5989921741a63c45ed536754d..98aaeadd5cf3beb79eba5d021a90334e72346e5b 100644 --- a/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java +++ b/gms/src/main/java/it/inaf/ia2/gms/service/GroupNameService.java @@ -46,9 +46,6 @@ public class GroupNameService { Set<String> groupIds = groups.stream().map(g -> g.getId()).collect(Collectors.toSet()); List<String> names = new ArrayList<>(groupsDAO.getGroupCompleteNamesFromId(groupIds).values()); - if (groupIds.contains("ROOT")) { - names.add(getRoot().getName()); - } Collections.sort(names); diff --git a/gms/src/main/resources/sql/init.sql b/gms/src/main/resources/sql/init.sql index 56103d17830c7a050f92fbc250e40f74188d6910..41360a8b799a960fd6a51a32a6a534effbe99eeb 100644 --- a/gms/src/main/resources/sql/init.sql +++ b/gms/src/main/resources/sql/init.sql @@ -74,5 +74,7 @@ FROM ( FROM gms_group ) AS p ON g.id = p.rel_id ORDER BY p.id, nlevel(g.path) -) AS j -GROUP BY id ORDER BY complete_name; +) AS j GROUP BY id +UNION +SELECT id, name AS complete_name FROM gms_group WHERE id = 'ROOT' +ORDER BY complete_name;