package eu.dnetlib.dnetrolemanagement.controllers; import com.google.gson.Gson; import com.google.gson.JsonArray; import eu.dnetlib.dnetrolemanagement.entities.Response; import eu.dnetlib.dnetrolemanagement.entities.User; import eu.dnetlib.dnetrolemanagement.exception.ConflictException; import eu.dnetlib.dnetrolemanagement.exception.ResourceNotFoundException; import eu.dnetlib.dnetrolemanagement.exception.UnprocessableException; import eu.dnetlib.dnetrolemanagement.services.RegistryService; import eu.dnetlib.dnetrolemanagement.utils.AuthoritiesUpdater; import eu.dnetlib.dnetrolemanagement.utils.AuthoritiesUtils; import eu.dnetlib.dnetrolemanagement.utils.JsonUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.HttpClientErrorException; import java.util.List; @RestController @RequestMapping("/member") public class MemberController { private final RegistryService registryService; private final AuthoritiesUpdater authoritiesUpdater; private final Gson gson; @Autowired public MemberController(RegistryService registryService, AuthoritiesUpdater authoritiesUpdater) { this.registryService = registryService; this.authoritiesUpdater = authoritiesUpdater; this.gson = new Gson(); } /** * Create a new Group for an entity (only for admins) */ @RequestMapping(value = "/{type}/{id}/create", method = RequestMethod.POST) public ResponseEntity createGroup(@PathVariable("type") String type, @PathVariable("id") String id, @RequestParam(value = "description", required = false) String description) { try { if (registryService.getCouId(AuthoritiesUtils.memberRole(type, id)) == null) { registryService.createRole(AuthoritiesUtils.memberRole(type, id), description != null ? description : ""); return ResponseEntity.ok(new Response("Role has been created successfully")); } else { throw new ConflictException("This role already exists"); } } catch (HttpClientErrorException e) { throw new ConflictException("This role already exists"); } } /** * Get the user info of the members of a type(Community, etc.) with id(ee, egi, etc.) */ @RequestMapping(value = "/{type}/{id}", method = RequestMethod.GET) public ResponseEntity getAll(@PathVariable("type") String type, @PathVariable("id") String id, @RequestParam(value = "isManager", required = false, defaultValue = "true") boolean isManager, @RequestParam(value = "email", required = false, defaultValue = "true") boolean email, @RequestParam(value = "name", required = false, defaultValue = "true") boolean name) { Integer couId = registryService.getCouId(AuthoritiesUtils.memberRole(type, id)); if (couId != null) { JsonArray users = registryService.getUserIdByCouId(couId, false); JsonArray emails = (email) ? registryService.getUserEmailByCouId(couId, false) : new JsonArray(); JsonArray names = (name) ? registryService.getUserNamesByCouId(couId, false) : new JsonArray(); if (isManager) { JsonArray managers = registryService.getUserIdByCouId(couId, true); users.getAsJsonArray().forEach(element -> { element.getAsJsonObject().addProperty("isManager", managers.contains(element)); }); } return ResponseEntity.ok(JsonUtils.mergeUserInfo(users, emails, names, gson)); } throw new ResourceNotFoundException("Role has not been found"); } /** * Get the number of the members of a type(Community, etc.) with id(ee, egi, etc.) */ @RequestMapping(value = "/{type}/{id}/count", method = RequestMethod.GET) public ResponseEntity getCount(@PathVariable("type") String type, @PathVariable("id") String id) { Integer couId = registryService.getCouId(AuthoritiesUtils.memberRole(type, id)); if (couId != null) { JsonArray users = registryService.getUserIdByCouId(couId, false); return ResponseEntity.ok((users.size())); } throw new ResourceNotFoundException("Role has not been found"); } /** * Assign member role to logged in user or user with @email * If role doesn't exist, use force=true to create and assign the role */ @RequestMapping(value = "/{type}/{id}", method = RequestMethod.POST) public ResponseEntity assignRole(@PathVariable("type") String type, @PathVariable("id") String id, @RequestParam(required = false) String email, @RequestParam(value = "force", defaultValue = "false") boolean force) { List coPersonIds = registryService.getCoPersonIdsByEmail(email); if (coPersonIds.size() > 0) { Integer temp = registryService.getCouId(AuthoritiesUtils.memberRole(type, id)); if (temp != null || force) { Integer couId = (temp != null) ? temp : registryService.createRole(AuthoritiesUtils.memberRole(type, id), ""); coPersonIds.forEach(coPersonId -> { String identifier = registryService.getIdentifierByCoPersonId(coPersonId); Integer role = registryService.getRoleId(coPersonId, couId); registryService.assignMemberRole(coPersonId, couId, role); authoritiesUpdater.addRole(identifier, new SimpleGrantedAuthority(AuthoritiesUtils.member(type, id))); }); return ResponseEntity.ok(new Response("Role has been assigned successfully")); } throw new ResourceNotFoundException("Role has not been found"); } throw new ResourceNotFoundException("User has not been found"); } /** * Remove member role from logged in user or user with @email * If user is an admin of this group, use force=true to revoke both roles */ @RequestMapping(value = "/{type}/{id}", method = RequestMethod.DELETE) public ResponseEntity removeRole(@PathVariable("type") String type, @PathVariable("id") String id, @RequestParam(required = false) String email, @RequestParam(value = "force", defaultValue = "false") boolean force) { List coPersonIds = registryService.getCoPersonIdsByEmail(email); if (coPersonIds.size() > 0) { Integer couId = registryService.getCouId(AuthoritiesUtils.memberRole(type, id)); if (couId != null) { // If none of the accounts has admin role for this group remove member role if (force || coPersonIds.stream().noneMatch(coPersonId -> registryService.getUserAdminGroup(coPersonId, couId) != null)) { coPersonIds.forEach(coPersonId -> { String identifier = registryService.getIdentifierByCoPersonId(coPersonId); Integer role = registryService.getRoleId(coPersonId, couId); if (force) { registryService.removeAdminRole(coPersonId, couId); authoritiesUpdater.removeRole(identifier, new SimpleGrantedAuthority(AuthoritiesUtils.manager(type, id))); } registryService.removeMemberRole(coPersonId, couId, role); authoritiesUpdater.removeRole(identifier, new SimpleGrantedAuthority(AuthoritiesUtils.member(type, id))); }); return ResponseEntity.ok(new Response("Role has been revoked successfully")); } throw new UnprocessableException("Remove admin role first"); } throw new ResourceNotFoundException("Role has not been found"); } throw new ResourceNotFoundException("User has not been found"); } }