package eu.dnetlib.openaire.usermanagement.api; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import eu.dnetlib.openaire.user.pojos.RoleVerification; import eu.dnetlib.openaire.user.utils.EmailSender; import eu.dnetlib.openaire.usermanagement.utils.AuthorizationService; import eu.dnetlib.openaire.usermanagement.utils.JsonUtils; import eu.dnetlib.openaire.usermanagement.utils.RoleManagement; import eu.dnetlib.openaire.usermanagement.utils.VerificationUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.client.HttpClientErrorException; import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Component(value = "RegistryService") @CrossOrigin("*") @Path("/registry") public class RegistryService { private static final Logger logger = Logger.getLogger(RegistryService.class); @Autowired private RoleManagement calls; @Autowired private JsonUtils jsonUtils; @Autowired private VerificationUtils verificationUtils; @Autowired private EmailSender emailSender; @Autowired private AuthorizationService authorizationService; /** * Subscribe to a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/subscribe/{type}/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated() and @AuthorizationService.isCommunity(#type)") public Response subscribe(@PathParam("type") String type, @PathParam("id") String id, @Context final HttpServletRequest request) { try { JsonElement response = calls.assignMemberRole(type, id, request); return Response.status(HttpStatus.OK.value()).entity(response.toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Unsubscribe from type(Community, etc.) with id(ee, egi, etc.). * If user has manager role for this entity, it will be removed too. */ @Path("/unsubscribe/{type}/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated() and @AuthorizationService.isCommunity(#type)") public Response unsubscribe(@PathParam("type") String type, @PathParam("id") String id, @Context final HttpServletRequest request) { try { JsonElement response = calls.removeMemberRole(type, id, request); return Response.status(HttpStatus.OK.value()).entity(response.toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Create a new curator role with the given type(Community, etc.). **/ @Path("/create/{type}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN)") public Response createCuratorRole(@PathParam("type") String type) { try { JsonElement response = calls.createCuratorRole(type); return Response.status(HttpStatus.CREATED.value()).entity(response.toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Create a new role with the given type(Community, etc.) with id(ee, egi, etc.). **/ @Path("/create/{type}/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, @AuthorizationService.curator(#type))") public Response createMemberRole(@PathParam("type") String type, @PathParam("id") String id) { JsonElement element = null; Response response = null; try { if(type.equals("ri") || type.equals("community")) { element = calls.createMemberRole("ri", id); } else { element = calls.createMemberRole(type, id); } } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); response = Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } finally { try { if(type.equals("ri") || type.equals("community")) { element = calls.createMemberRole("community", id); } if(element != null) { response = Response.status(HttpStatus.CREATED.value()).entity(element.toString()).type(MediaType.APPLICATION_JSON).build(); } } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); response = Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } return response; } /** * Invite user with email to manage a type(Community, etc.) with id(ee, egi, etc.) * Auto generated link and code will be sent as response. */ @Path("/invite/{type}/{id}/manager") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response inviteManager(@PathParam("type") String type, @PathParam("id") String id, @RequestBody String body) { try { JsonObject details = new JsonParser().parse(body).getAsJsonObject(); JsonObject email = details.get("email").getAsJsonObject(); String recipient = email.get("recipient").getAsString(); if (!calls.isManager(type, id, recipient)) { JsonObject invitation = verificationUtils.createManagerInvitation(recipient, type, id); return sendEmail(details, email, invitation); } else { return Response.status(HttpStatus.CONFLICT.value()).entity(jsonUtils.createResponse("User has been already manager of this " + type).toString()).type(MediaType.APPLICATION_JSON).build(); } } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Invite user with email to be a member of a type(Community, etc.) with id(ee, egi, etc.) * Auto generated link and code will be sent as response. */ @Path("/invite/{type}/{id}/member") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response inviteMember(@PathParam("type") String type, @PathParam("id") String id, @RequestBody String body) { try { JsonObject details = new JsonParser().parse(body).getAsJsonObject(); JsonObject email = details.get("email").getAsJsonObject(); String recipient = email.get("recipient").getAsString(); if (!calls.isMember(type, id, recipient)) { JsonObject invitation = verificationUtils.createMemberInvitation(recipient, type, id); return sendEmail(details, email, invitation); } else { return Response.status(HttpStatus.CONFLICT.value()).entity(jsonUtils.createResponse("User has been already member of this " + type).toString()).type(MediaType.APPLICATION_JSON).build(); } } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } private Response sendEmail(JsonObject details, JsonObject email, JsonObject invitation) { String link = details.get("link").getAsString() + invitation.get("link").getAsString(); String subject = email.get("subject").getAsString(); String message = email.get("body").getAsString(). replace("((__user__))", "User"). replace("((__link__))", link). replace("((__code__))", invitation.get("code").getAsString()); try { emailSender.sendEmail(email.get("recipient").getAsString(), subject, message); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(invitation).toString()).type(MediaType.APPLICATION_JSON).build(); } catch (MessagingException e) { verificationUtils.deleteVerification(invitation.get("link").getAsString()); return Response.status(HttpStatus.BAD_REQUEST.value()).entity(jsonUtils.createResponse("Email sent failed").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Cancel invitation to user with email for managing a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/invite/{type}/{id}/manager/{email}") @DELETE @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response cancelManagerInvitations(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { verificationUtils.deleteManagerVerifications(email, type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Invitations have been deleted").toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Cancel invitation to user with email for being member of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/invite/{type}/{id}/member/{email}") @DELETE @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response cancelMemberInvitations(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { verificationUtils.deleteMemberVerifications(email, type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Invitations have been deleted").toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the invited managers for a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/invite/{type}/{id}/managers/") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response getInvitedManagers(@PathParam("type") String type, @PathParam("id") String id) { JsonArray invited = verificationUtils.getInvitedManagers(type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(invited).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the invited members for a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/invite/{type}/{id}/members/") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, " + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response getInviteMembers(@PathParam("type") String type, @PathParam("id") String id) { JsonArray invited = verificationUtils.getInvitedMembers(type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(invited).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the verification with a specific id only if it refers to the logged in user */ @Path("/verification/{id}") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated()") public Response getVerification(@PathParam("id") String id) { RoleVerification verification = verificationUtils.getVerification(id); if (verification != null) { if (verification.getEmail().equalsIgnoreCase(authorizationService.getEmail())) { return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(jsonUtils.createVerification(verification)).toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.FORBIDDEN.value()).entity(jsonUtils.createResponse("Forbidden verification").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Verification has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Delete the verification with a specific id. */ @Path("/verification/{id}") @DELETE @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated() && @VerificationUtils.ownedVerification(#id)") public Response deleteVerification(@PathParam("id") String id) { if (verificationUtils.getVerification(id) != null) { verificationUtils.deleteVerification(id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(jsonUtils.createResponse("Verification deleted")).toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse(jsonUtils.createResponse("Verification has not been found")).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Verify the verification with the specific id, if the code is correct and it refers to the logged in user. * Manager role is assigned to this user, along with the member role. */ @Path("/verification/manager/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated()") public Response verifyManager(@PathParam("id") String id, @RequestBody String code, @Context final HttpServletRequest request) { RoleVerification verification = verificationUtils.getVerification(id); if (verification != null && verification.getVerificationType().equals("manager")) { if (verification.getEmail().equalsIgnoreCase(authorizationService.getEmail())) { if (verification.getVerificationCode().equals(code)) { try { calls.assignManagerRole(verification.getType(), verification.getEntity(), request); if (verification.getType().equals("community") || verification.getType().equals("ri")) { calls.assignMemberRole("ri", verification.getEntity(), request); verificationUtils.deleteMemberVerifications(verification.getEmail(), "community", verification.getEntity()); verificationUtils.deleteMemberVerifications(verification.getEmail(), "ri", verification.getEntity()); verificationUtils.deleteManagerVerifications(verification.getEmail(), "community", verification.getEntity()); verificationUtils.deleteManagerVerifications(verification.getEmail(), "ri", verification.getEntity()); } else { verificationUtils.deleteMemberVerifications(verification.getEmail(), verification.getType(), verification.getEntity()); verificationUtils.deleteManagerVerifications(verification.getEmail(), verification.getType(), verification.getEntity()); } return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Admin role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.BAD_REQUEST.value()).entity(jsonUtils.createResponse("Verification code is wrong").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.FORBIDDEN.value()).entity(jsonUtils.createResponse("Forbidden verification").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Verification has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Verify the verification with the specific id, if the code is correct and it refers to the logged in user. * Member role is assigned to this user, along with the member role. */ @Path("/verification/member/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated()") public Response verifyMember(@PathParam("id") String id, @RequestBody String code, @Context final HttpServletRequest request) { RoleVerification verification = verificationUtils.getVerification(id); if (verification != null && verification.getVerificationType().equals("member")) { if (verification.getEmail().equalsIgnoreCase(authorizationService.getEmail())) { if (verification.getVerificationCode().equals(code)) { try { calls.assignMemberRole(verification.getType(), verification.getEntity(), request); verificationUtils.deleteMemberVerifications(verification.getEmail(), verification.getType(), verification.getEntity()); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Member role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.BAD_REQUEST.value()).entity(jsonUtils.createResponse("Verification code is wrong").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.FORBIDDEN.value()).entity(jsonUtils.createResponse("Forbidden verification").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Verification has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Remove the manager role from user with email for a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/manager/{email}") @DELETE @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, @AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response removeManagerRole(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { try { JsonElement response = calls.removeManagerRole(type, id, email); return Response.status(HttpStatus.OK.value()).entity(response.toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Remove the member role from user with email for a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/member/{email}") @DELETE @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, @AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response removeMemberRole(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { try { JsonElement response = calls.removeMemberRole(type, id, email); return Response.status(HttpStatus.OK.value()).entity(response.toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Get the number of the members of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/members/count") @GET @Produces(MediaType.APPLICATION_JSON) public Response getMembersCount(@PathParam("type") String type, @PathParam("id") String id) { try { int response = calls.getAllMembersCount(type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(response).toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Get infos of the members of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/members{var:.*}") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN," + "@AuthorizationService.curator(#type), @AuthorizationService.manager(#type, #id))") public Response getMembers(@PathParam("type") String type, @PathParam("id") String id) { try { JsonElement response = calls.getAllMembers(type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(response).toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Get infos of the managers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/managers{var:.*}") @GET @Produces(MediaType.APPLICATION_JSON) public Response getManagers(@PathParam("type") String type, @PathParam("id") String id) { try { JsonElement response = calls.getAllManagers(type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(response).toString()).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Get infos of the curators of a type(Community, etc.) */ @Path("/{type}/curators{var:.*}") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthorizationService.PORTAL_ADMIN, @AuthorizationService.curator(#type))") public Response getCurators(@PathParam("type") String type) { try { JsonElement response = calls.getAllCurators(type); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(response.toString())).type(MediaType.APPLICATION_JSON).build(); } catch (HttpClientErrorException e) { String message = new JsonParser().parse(e.getResponseBodyAsString()).getAsJsonObject().get("message").getAsString(); return Response.status(e.getStatusCode().value()).entity(jsonUtils.createResponse(message).toString()).type(MediaType.APPLICATION_JSON).build(); } } }