package eu.dnetlib.openaire.usermanagement.api; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import eu.dnetlib.openaire.user.pojos.ManagerVerification; import eu.dnetlib.openaire.user.utils.EmailSender; import eu.dnetlib.openaire.usermanagement.dto.Role; import eu.dnetlib.openaire.usermanagement.utils.JsonUtils; import eu.dnetlib.openaire.usermanagement.utils.RegistryCalls; 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.RequestBody; import javax.mail.MessagingException; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Component(value = "RegistryService") @Path("/registry") public class RegistryService { private static final Logger logger = Logger.getLogger(RegistryService.class); @Autowired private RegistryCalls calls; @Autowired private JsonUtils jsonUtils; @Autowired private EmailSender emailSender; @Autowired private VerificationUtils verificationUtils; /** * Subscribe to a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/subscribe/{type}/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated()") public Response subscribe(@PathParam("type") String type, @PathParam("id") String id) { Integer coPersonId = calls.getCoPersonIdByIdentifier(); Integer couId = calls.getCouId(type, id); if (couId != null) { Integer role = calls.getRoleId(coPersonId, couId); calls.assignMemberRole(coPersonId, couId, role); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Subscribe 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()") public Response unsubscribe(@PathParam("type") String type, @PathParam("id") String id) { Integer coPersonId = calls.getCoPersonIdByIdentifier(); Integer couId = calls.getCouId(type, id); if (couId != null) { Integer role = calls.getRoleId(coPersonId, couId); if (role != null) { calls.removeAdminRole(coPersonId, couId); calls.removeMemberRole(coPersonId, couId, role); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Role has been removed").toString()).type(MediaType.APPLICATION_JSON).build(); } else return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("User does not have this role").toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Create a new role with the given name and description. **/ @Path("/createRole") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.USER_ADMIN)") public Response createRole(@RequestBody Role role) { calls.createRole(role); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Role has been created").toString()).type(MediaType.APPLICATION_JSON).build(); } /** * 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/{email}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.USER_ADMIN, @AuthoritiesService.PORTAL_ADMIN, " + "@AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response inviteUser(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email, @RequestBody String body) { Integer couId = calls.getCouId(type, id); if (couId != null) { Integer coPersonId = calls.getCoPersonIdByEmail(email); if (calls.getUserAdminGroup(coPersonId, couId) == null) { JsonObject invitation = verificationUtils.createInvitation(email, type, id); String name = calls.getUserNames(coPersonId); JsonObject details = new JsonParser().parse(body).getAsJsonObject(); String link = details.get("link").getAsString() + "/" + invitation.get("link").getAsString(); String subject = "Invite to manage " + details.get("name").getAsString(); String message = "

Hello " + name + ",

" + "

You have been invited to manage " + details.get("name").getAsString() + ". " + "Use the verification code below to accept the invitation." + "

" + "

" + "The verification code is " + invitation.get("code").getAsString() + "

" + "Click the URL below and proceed with the process." + "

" + link + "

" + "

Thank you,

" + "

OpenAIRE technical team

"; try { emailSender.sendEmail(email, subject, message); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(invitation).toString()).type(MediaType.APPLICATION_JSON).build(); } catch (MessagingException e) { logger.error(e.getMessage()); 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(); } } else { return Response.status(HttpStatus.CONFLICT.value()).entity(jsonUtils.createResponse("User has been already manager of this " + type).toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").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(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.USER_ADMIN, @AuthoritiesService.PORTAL_ADMIN, " + "@AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response cancelUserInvitations(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { Integer couId = calls.getCouId(type, id); if (couId != null) { verificationUtils.deleteUserVerifications(email, type, id); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Invitations have been deleted").toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").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(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.USER_ADMIN, @AuthoritiesService.PORTAL_ADMIN, " + "@AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response getInvitedManagers(@PathParam("type") String type, @PathParam("id") String id) { JsonArray invited = verificationUtils.getInvitedUsers(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) { ManagerVerification managerVerification = verificationUtils.getVerification(id); if (managerVerification != null) { if (calls.getCoPersonIdByEmail(managerVerification.getEmail()).equals(calls.getCoPersonIdByIdentifier())) { return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(jsonUtils.createVerification(managerVerification)).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/{id}") @POST @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("isAuthenticated()") public Response verify(@PathParam("id") String id, @RequestBody String code) { ManagerVerification managerVerification = verificationUtils.getVerification(id); if (managerVerification != null) { Integer coPersonId = calls.getCoPersonIdByEmail(managerVerification.getEmail()); if (coPersonId != null) { if (coPersonId.equals(calls.getCoPersonIdByIdentifier())) { if (managerVerification.getVerificationCode().equals(code)) { verificationUtils.deleteRelatedVerifications(managerVerification); Integer couId = calls.getCouId(managerVerification.getType(), managerVerification.getEntity()); if (couId != null) { Integer role = calls.getRoleId(coPersonId, couId); calls.assignMemberRole(coPersonId, couId, role); if (calls.getUserAdminGroup(coPersonId, couId) == null) { calls.assignAdminRole(coPersonId, couId); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Admin role has been assigned").toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.CONFLICT.value()).entity(jsonUtils.createResponse("User is already admin of this cou").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.FORBIDDEN.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("User has not been found").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(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.USER_ADMIN," + "@AuthoritiesService.PORTAL_ADMIN, @AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response removeManagerRole(@PathParam("type") String type, @PathParam("id") String id, @PathParam("email") String email) { Integer coPersonId = calls.getCoPersonIdByEmail(email); if (coPersonId != null) { Integer couId = calls.getCouId(type, id); if (couId != null) { calls.removeAdminRole(coPersonId, couId); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse("Role has been removed").toString()).type(MediaType.APPLICATION_JSON).build(); } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("Role has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } else { return Response.status(HttpStatus.NOT_FOUND.value()).entity(jsonUtils.createResponse("User has not been found").toString()).type(MediaType.APPLICATION_JSON).build(); } } /** * Get the names of the subscribers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/subscribers") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.PORTAL_ADMIN," + "@AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response getSubscribers(@PathParam("type") String type, @PathParam("id") String id) { Integer couId = calls.getCouId(type, id); JsonArray subscribers = calls.getUserNamesByCouId(couId, false); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(subscribers).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the emails of the subscribers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/subscribers/email") @GET @Produces(MediaType.APPLICATION_JSON) @PreAuthorize("hasAnyAuthority(@AuthoritiesService.SUPER_ADMIN, @AuthoritiesService.PORTAL_ADMIN," + "@AuthoritiesService.curator(#type), @AuthoritiesService.manager(#type, #id))") public Response getSubscribersEmail(@PathParam("type") String type, @PathParam("id") String id) { Integer couId = calls.getCouId(type, id); JsonArray subscribers = calls.getUserEmailByCouId(couId, false); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(subscribers).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the number of the subscribers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/subscribers/count") @GET @Produces(MediaType.APPLICATION_JSON) public Response getSubscribersCount(@PathParam("type") String type, @PathParam("id") String id) { Integer couId = calls.getCouId(type, id); int count = calls.getUserNamesByCouId(couId, false).size(); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(count).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the names of the managers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/managers") @GET @Produces(MediaType.APPLICATION_JSON) public Response getManagers(@PathParam("type") String type, @PathParam("id") String id) { Integer couId = calls.getCouId(type, id); JsonArray managers = calls.getUserNamesByCouId(couId, true); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(managers).toString()).type(MediaType.APPLICATION_JSON).build(); } /** * Get the emails of the managers of a type(Community, etc.) with id(ee, egi, etc.) */ @Path("/{type}/{id}/managers/email") @GET @Produces(MediaType.APPLICATION_JSON) public Response getManagersEmail(@PathParam("type") String type, @PathParam("id") String id) { Integer couId = calls.getCouId(type, id); JsonArray managers = calls.getUserEmailByCouId(couId, true); return Response.status(HttpStatus.OK.value()).entity(jsonUtils.createResponse(managers).toString()).type(MediaType.APPLICATION_JSON).build(); } }