package org.gcube.portal.invites; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import javax.mail.internet.AddressException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.codec.binary.Base64; import org.gcube.common.portal.PortalContext; import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl; import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.databook.shared.Invite; import org.gcube.portal.databook.shared.InviteOperationResult; import org.gcube.portal.databook.shared.InviteStatus; import org.gcube.portal.databook.shared.ex.InviteIDNotFoundException; import org.gcube.portal.databook.shared.ex.InviteStatusNotFoundException; import org.gcube.portal.mailing.message.EmailAddress; import org.gcube.portal.mailing.message.Recipient; import org.gcube.portal.mailing.message.RecipientType; import org.gcube.portal.mailing.service.EmailTemplateService; import org.gcube.portal.mailing.templates.TemplateUserHasInvited; import org.gcube.portal.mailing.templates.TemplatedJoinMeInvite; import org.gcube.portal.mailing.templates.TemplatenviteWIthPassword; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeRole; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Massimiliano Assante * */ public class InvitesManager { private static final Logger _log = LoggerFactory.getLogger(InvitesManager.class); public static final String SITEID_ATTR ="siteId"; public static final String INVITEID_ATTR ="inviteId"; public static final String INVITE_PAGE_ENDPOINT = "manage-invite"; public static final int RANDOM_PASSWD_LENGTH = 8; private static InvitesManager instance; private static DatabookStore store; private InvitesManager() { } public static InvitesManager getInstance(){ instance = new InvitesManager(); initStore(); return instance; } /** * * @return the unique instance of the store */ public static synchronized DatabookStore initStore() { if (store == null) { store = new DBCassandraAstyanaxImpl(); } return store; } public InviteOperationResult sendInvite( HttpServletRequest request, String portalSenderEmail, String portalURL, String name, String lastName, String email, String vreDescription) { GCubeUser currUser = PortalContext.getConfiguration().getCurrentUser(request); String username = currUser.getUsername(); String fromFullName = currUser.getFullname(); String controlcode = GenerateSecurePassword.generatePassword(RANDOM_PASSWD_LENGTH); String currScope = PortalContext.getConfiguration().getCurrentScope(request); Invite invite = new Invite(UUID.randomUUID().toString(), username, currScope, email, controlcode, InviteStatus.PENDING, new Date(), fromFullName); InviteOperationResult result = null; boolean accountExists = true; try { new LiferayUserManager().getUserByEmail(invite.getInvitedEmail()); } catch (UserManagementSystemException | UserRetrievalFault e) { _log.info("No user account exist with this email " + invite.getInvitedEmail() + " sending email with password temp."); accountExists = false; } boolean emailResult = false; try { String vreName = PortalContext.getConfiguration().getCurrentGroupName(request); result = store.saveInvite(invite); if (result == InviteOperationResult.ALREADY_INVITED) { //if the invite existed already the id and temp passwd has to be the same of the original invite (in the persistence) String inviteid = store.isExistingInvite(currScope, email); invite.setKey(inviteid); String tempPwd = store.readInvite(inviteid).getControlCode(); invite.setControlCode(tempPwd);; } emailResult = sendInviteEmail(request, invite, currUser, vreName, name, email, vreDescription, accountExists); notifyInviteSent(request, currUser, currScope, invite, vreName); } catch (AddressException e) { _log.error("Email not valid " + e.getMessage()); e.printStackTrace(); return InviteOperationResult.FAILED; } catch (Exception e) { _log.error("Something wrong happened retrieving the invite which seemd to be existing already " + e.getMessage()); e.printStackTrace(); return InviteOperationResult.FAILED; } return (emailResult) ? result : InviteOperationResult.FAILED; } private Boolean sendInviteEmail( HttpServletRequest request, Invite invite, GCubeUser currUser, String vreName, String name, String email, String vreDescription, boolean accountExists) { PortalContext pContext = PortalContext.getConfiguration(); String gatewayURL = pContext.getGatewayURL(request); String gatewayName = pContext.getGatewayName(request); try { String subject = "Join me on " + vreName + " VRE"; long groupId = PortalContext.getConfiguration().getCurrentGroupId(request); StringBuilder getParamsEncoded = new StringBuilder(URLEncoder.encode(new String(Base64.encodeBase64(INVITEID_ATTR.getBytes())), "UTF-8")) .append("=") .append(URLEncoder.encode(new String(Base64.encodeBase64(invite.getKey().getBytes())), "UTF-8")) .append("&") .append(URLEncoder.encode(new String(Base64.encodeBase64(SITEID_ATTR.getBytes())), "UTF-8")) .append("=") .append(URLEncoder.encode(new String(Base64.encodeBase64((""+groupId).getBytes())), "UTF-8")); StringBuilder linkToAcceptInvite = new StringBuilder(gatewayURL) .append("/") .append(INVITE_PAGE_ENDPOINT) .append("?") .append(getParamsEncoded); if (accountExists) { EmailTemplateService.send( subject, new TemplatedJoinMeInvite(gatewayName, gatewayURL, currUser, name, vreName, vreDescription, linkToAcceptInvite.toString()), request, new Recipient(email), new Recipient(new EmailAddress(currUser.getEmail()), RecipientType.CC)); } else { //the user account does not exists yet, it needs to be created on KC and a random pwd to be sent to the user in the email EmailTemplateService.send( subject, new TemplatenviteWIthPassword(gatewayName, gatewayURL, currUser, name, vreName, vreDescription, linkToAcceptInvite.toString(), invite.getControlCode()), request, new Recipient(email), new Recipient(new EmailAddress(currUser.getEmail()), RecipientType.CC)); } _log.debug("Join Me Invite email message sent successfully to " + email ); } catch (Exception mex) { mex.printStackTrace(); _log.error("Sent message ERROR to " + email ); return false; } return true; } /** * * @param request * @param username * @param scope * @param invite * @param vreName */ public static void notifyInviteSent(HttpServletRequest request, GCubeUser currUser, String scope, Invite invite, String vreName) { List adminRecipients = new ArrayList<>(); for (String email : getAdministratorsEmails(scope)) { adminRecipients.add(new Recipient(email)); } String gatewayURL = PortalContext.getConfiguration().getGatewayURL(request); String gatewayName = PortalContext.getConfiguration().getGatewayName(request); String subject = new StringBuffer("An invite was sent on ").append(vreName).append(" by ").append(invite.getSenderFullName()).toString(); EmailTemplateService.send( subject, new TemplateUserHasInvited(currUser, invite.getInvitedEmail(), vreName, gatewayName, gatewayURL), request, adminRecipients.toArray(new Recipient[adminRecipients.size()])); } private static ArrayList getAdministratorsEmails(String scope) { LiferayUserManager userManager = new LiferayUserManager(); LiferayGroupManager groupManager = new LiferayGroupManager(); long groupId = -1; try { List allGroups = groupManager.listGroups(); _log.debug("Number of groups retrieved: " + allGroups.size()); for (int i = 0; i < allGroups.size(); i++) { long grId = allGroups.get(i).getGroupId(); String groupScope = groupManager.getInfrastructureScope(grId); _log.debug("Comparing: " + groupScope + " " + scope); if (groupScope.equals(scope)) { groupId = allGroups.get(i).getGroupId(); break; } } } catch (UserManagementSystemException e) { e.printStackTrace(); } catch (GroupRetrievalFault e) { e.printStackTrace(); } Map> usersAndRoles = null; try { usersAndRoles = userManager.listUsersAndRolesByGroup(groupId); } catch (Exception e) { e.printStackTrace(); } Set users = usersAndRoles.keySet(); ArrayList adminEmailsList = new ArrayList(); for (GCubeUser usr:users) { List roles = usersAndRoles.get(usr); for (int i = 0; i < roles.size(); i++) { if (roles.get(i).getRoleName().equals("VO-Admin") || roles.get(i).getRoleName().equals("VRE-Manager")) { adminEmailsList.add(usr.getEmail()); _log.debug("Admin: " + usr.getFullname()); break; } } } return adminEmailsList; } }