diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index fffd28a..f7f0893 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,7 +1,7 @@ - + diff --git a/pom.xml b/pom.xml index b2f1d21..ee93f7b 100644 --- a/pom.xml +++ b/pom.xml @@ -11,13 +11,13 @@ org.gcube.portal social-mail-servlet war - 1.4.0-SNAPSHOT + 2.0.0-SNAPSHOT social-mail-servlet Webapp This component read periodically email replies from user wanting to reply to a post via email 1.7 - 6.0.6 + 6.2.5 ${project.basedir}/distro ${project.build.directory}/${project.build.finalName} distro diff --git a/src/main/java/org/gcube/portal/PortalSchedulerService.java b/src/main/java/org/gcube/portal/PortalSchedulerService.java index c756fe1..a5c09e2 100644 --- a/src/main/java/org/gcube/portal/PortalSchedulerService.java +++ b/src/main/java/org/gcube/portal/PortalSchedulerService.java @@ -4,6 +4,7 @@ import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -18,16 +19,26 @@ import org.gcube.common.encryption.StringEncrypter; import org.gcube.common.portal.PortalContext; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; -import org.gcube.common.resources.gcore.utils.Group; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl; import org.gcube.portal.databook.server.DatabookStore; +import org.gcube.portal.socialmail.EmailPopAccount; import org.gcube.portal.socialmail.PeriodicTask; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; +import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; +import org.gcube.vomanagement.usermanagement.model.CustomAttributeKeys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.liferay.portal.kernel.exception.PortalException; +import com.liferay.portal.kernel.exception.SystemException; +import com.liferay.portal.model.Group; +import com.liferay.portal.model.VirtualHost; +import com.liferay.portal.service.LayoutSetLocalServiceUtil; +import com.liferay.portal.service.VirtualHostLocalServiceUtil; + @SuppressWarnings("serial") public class PortalSchedulerService extends HttpServlet { @@ -35,52 +46,105 @@ public class PortalSchedulerService extends HttpServlet { private static final Logger _log = LoggerFactory.getLogger(PortalSchedulerService.class); private static final String POP3_SERVER_NAME = "Pop3MailServer"; - + private static final int POP3_MINUTES_DELAY = 1; - private static DatabookStore store; - - private String portalName; - private String pop3Server; - private String pop3user; - private String pop3password; - - + public void init() { store = new DBCassandraAstyanaxImpl(); - portalName = PortalContext.getPortalInstanceName(); + } + + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + Group site; + EmailPopAccount popAccount = null; + try { + site = getSiteFromServletRequest(request); + popAccount = getPopAccountData(site); + } catch (Exception e) { + e.printStackTrace(); + } + + ScheduledExecutorService pop3Scheduler = Executors.newScheduledThreadPool(1); + pop3Scheduler.scheduleAtFixedRate(new PeriodicTask(store, popAccount, request), 0, POP3_MINUTES_DELAY, TimeUnit.MINUTES); + + String toReturn = "
Check Notification Email Started ...
"; + + response.setContentType("text/html"); + response.getWriter().write(toReturn); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} + + /** + * + * @param request + * @return the current Group instance based on the request + * @throws PortalException + * @throws SystemException + */ + private Group getSiteFromServletRequest(final HttpServletRequest request) throws PortalException, SystemException { + String serverName = request.getServerName(); + _log.debug("currentHost is " + serverName); + Group site = null; + List vHosts = VirtualHostLocalServiceUtil.getVirtualHosts(0, VirtualHostLocalServiceUtil.getVirtualHostsCount()); + for (VirtualHost virtualHost : vHosts) { + _log.debug("Found " + virtualHost.getHostname()); + if (virtualHost.getHostname().compareTo("localhost") != 0 && + virtualHost.getLayoutSetId() != 0 && + virtualHost.getHostname().compareTo(serverName) == 0) { + long layoutSetId = virtualHost.getLayoutSetId(); + site = LayoutSetLocalServiceUtil.getLayoutSet(layoutSetId).getGroup(); + _log.debug("Found match! Your site is " + site.getName()); + return site; + } + } + return null; + } + + private EmailPopAccount getPopAccountData(Group site) throws GroupRetrievalFault { + _log.debug("Found site for vhost, name " + site.getName() + " reading custom field: " + CustomAttributeKeys.GATEWAY_SITE_NAME); + String gatewayName = (String) new LiferayGroupManager().readCustomAttr(site.getGroupId(), CustomAttributeKeys.GATEWAY_SITE_NAME.getKeyName()); + + //set the scope for the query + String curScope = ScopeProvider.instance.get(); PortalContext context = PortalContext.getConfiguration(); - String scope = "/" + context.getInfrastructureName(); - ScopeProvider.instance.set(scope); - + String scope2Set = "/" + context.getInfrastructureName(); + ScopeProvider.instance.set(scope2Set); + + EmailPopAccount toReturn = new EmailPopAccount(); + toReturn.setPortalName(gatewayName); SimpleQuery query = queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Category/text() eq 'Portal'"); - query.addCondition("$resource/Profile/Name/text() eq '" + portalName + "'"); + query.addCondition("$resource/Profile/Name/text() eq '" + gatewayName + "'"); DiscoveryClient client = clientFor(ServiceEndpoint.class); List list = client.submit(query); if (list == null || list.isEmpty()) { - _log.error("Could not find any Service endpoint registred in the infrastructure for this portal: " + portalName); + _log.error("Could not find any Service endpoint registred in the infrastructure for this gateway: " + gatewayName); + return null; } else if (list.size() > 1) { - _log.warn("Found more than one Service endpoint registred in the infrastructure for this portal: " + portalName); + _log.warn("Found more than one Service endpoint registred in the infrastructure for this gateway: " + gatewayName); + return null; } else { for (ServiceEndpoint res : list) { - Group apGroup = res.profile().accessPoints(); + org.gcube.common.resources.gcore.utils.Group apGroup = res.profile().accessPoints(); AccessPoint[] accessPoints = (AccessPoint[]) apGroup.toArray(new AccessPoint[apGroup.size()]); for (int i = 0; i < accessPoints.length; i++) { if (accessPoints[i].name().compareTo(POP3_SERVER_NAME) == 0) { _log.info("Found credentials for " + POP3_SERVER_NAME); AccessPoint found = accessPoints[i]; - pop3Server = found.address(); - pop3user = found.username(); + toReturn.setPop3Server(found.address()); + toReturn.setPop3user(found.username()); String encrPassword = found.password(); try { - pop3password = StringEncrypter.getEncrypter().decrypt( encrPassword); + toReturn.setPop3password(StringEncrypter.getEncrypter().decrypt( encrPassword)); } catch (Exception e) { _log.error("Something went wrong while decrypting password for " + POP3_SERVER_NAME); e.printStackTrace(); @@ -89,18 +153,12 @@ public class PortalSchedulerService extends HttpServlet { } } } + //set the previous scope + ScopeProvider.instance.set(curScope); + return toReturn; } - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - ScheduledExecutorService pop3Scheduler = Executors.newScheduledThreadPool(1); - pop3Scheduler.scheduleAtFixedRate(new PeriodicTask(store, portalName, pop3Server, pop3user, pop3password), 0, POP3_MINUTES_DELAY, TimeUnit.MINUTES); - - String toReturn = "
Check Notification Email Started ...
"; - - response.setContentType("text/html"); - response.getWriter().write(toReturn); - } + + - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} } \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/socialmail/EmailPopAccount.java b/src/main/java/org/gcube/portal/socialmail/EmailPopAccount.java new file mode 100644 index 0000000..3d22804 --- /dev/null +++ b/src/main/java/org/gcube/portal/socialmail/EmailPopAccount.java @@ -0,0 +1,53 @@ +package org.gcube.portal.socialmail; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class EmailPopAccount implements Serializable { + private String portalName; + private String pop3Server; + private String pop3user; + private String pop3password; + + + public EmailPopAccount() { + this.portalName = ""; + this.pop3Server = ""; + this.pop3user = ""; + this.pop3password = ""; + } + + public EmailPopAccount(String portalName, String pop3Server, + String pop3user, String pop3password) { + super(); + this.portalName = portalName; + this.pop3Server = pop3Server; + this.pop3user = pop3user; + this.pop3password = pop3password; + } + public String getPortalName() { + return portalName; + } + public void setPortalName(String portalName) { + this.portalName = portalName; + } + public String getPop3Server() { + return pop3Server; + } + public void setPop3Server(String pop3Server) { + this.pop3Server = pop3Server; + } + public String getPop3user() { + return pop3user; + } + public void setPop3user(String pop3user) { + this.pop3user = pop3user; + } + public String getPop3password() { + return pop3password; + } + public void setPop3password(String pop3password) { + this.pop3password = pop3password; + } + +} diff --git a/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java index c05a874..2126e01 100644 --- a/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java +++ b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java @@ -19,6 +19,7 @@ import javax.mail.Session; import javax.mail.Store; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage.RecipientType; +import javax.servlet.http.HttpServletRequest; import org.gcube.application.framework.core.session.ASLSession; import org.gcube.application.framework.core.session.SessionManager; @@ -26,7 +27,8 @@ import org.gcube.application.framework.core.util.GenderType; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.NotificationsManager; import org.gcube.applicationsupportlayer.social.mailing.AppType; -import org.gcube.applicationsupportlayer.social.mailing.EmailPlugin; +import org.gcube.applicationsupportlayer.social.mailing.SocialMailingUtil; +import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.exceptions.HomeNotFoundException; @@ -37,7 +39,6 @@ import org.gcube.common.homelibrary.home.workspace.exceptions.WorkspaceFolderNot import org.gcube.common.homelibrary.home.workspace.sharing.WorkspaceMessage; import org.gcube.common.homelibrary.home.workspace.sharing.WorkspaceMessageManager; import org.gcube.common.portal.PortalContext; -import org.gcube.portal.custom.communitymanager.OrganizationsUtil; import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Feed; @@ -50,13 +51,12 @@ import org.gcube.portal.notifications.bean.GenericItemBean; import org.gcube.portal.notifications.thread.CommentNotificationsThread; import org.gcube.portal.notifications.thread.LikeNotificationsThread; import org.gcube.portal.notifications.thread.MessageNotificationsThread; +import org.gcube.vomanagement.usermanagement.UserManager; +import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; +import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.liferay.portal.kernel.exception.PortalException; -import com.liferay.portal.kernel.exception.SystemException; -import com.liferay.portal.model.User; -import com.liferay.portal.service.UserLocalServiceUtil; import com.sun.mail.util.MailSSLSocketFactory; /** @@ -68,24 +68,24 @@ public class PeriodicTask implements Runnable { private static final Logger _log = LoggerFactory.getLogger(PeriodicTask.class); private DatabookStore socialStore; - private String host; - private String mailserver_username; - private String password; - private String portalName; + private EmailPopAccount popAccount; + private SocialNetworkingSite site; - public PeriodicTask(DatabookStore store, String portalName, String host, String mailserver_username, String password) { + public PeriodicTask(DatabookStore store, EmailPopAccount popAccount, HttpServletRequest request) { super(); this.socialStore = store; - this.portalName = portalName; - this.host = host; - this.mailserver_username = mailserver_username; - this.password = password; + this.popAccount = popAccount; + this.site = new SocialNetworkingSite(request); + String serverName = request.getServerName(); + //needed because the servlet is called via http + this.site.setSiteURL("https://"+serverName); + _log.debug("PeriodicTask instanciated, request serverName=" + serverName); } @Override public void run() { - check(portalName, host, mailserver_username, password); + check(popAccount.getPortalName(), popAccount.getPop3Server(), popAccount.getPop3user(), popAccount.getPop3password()); } /** @@ -95,19 +95,17 @@ public class PeriodicTask implements Runnable { String sessionID = UUID.randomUUID().toString(); PortalContext context = PortalContext.getConfiguration(); String scope = "/" + context.getInfrastructureName(); - String username = ""; - long companyId; try { - companyId = OrganizationsUtil.getCompany().getCompanyId(); - User user = UserLocalServiceUtil.getUserByEmailAddress(companyId, emailAddress); - username = user.getScreenName(); + UserManager um = new LiferayUserManager(); + GCubeUser user = um.getUserByEmail(emailAddress); + username = user.getUsername(); SessionManager.getInstance().getASLSession(sessionID, username).setScope(scope); //add the social information needed by apps String fullName = user.getFirstName() + " " + user.getLastName(); - String email = user.getEmailAddress(); - String thumbnailURL = "/image/user_male_portrait?img_id="+user.getPortraitId(); + String email = user.getEmail(); + String thumbnailURL = user.getUserAvatarURL(); boolean isMale = user.isMale(); SessionManager.getInstance().getASLSession(sessionID, username).setUserFullName(fullName); @@ -117,7 +115,7 @@ public class PeriodicTask implements Runnable { _log.debug("Created fakesession for user " + username + " email="+emailAddress); - } catch (PortalException | SystemException e) { + } catch (Exception e) { _log.error("Exception while trying to get the user from email address: " + e.getMessage()); return null; } @@ -264,10 +262,11 @@ public class PeriodicTask implements Runnable { _log.debug("Message with subject: " + subject, " hase been sent, returned id: " + newMessageId); if (newMessageId != null) { - _log.debug("Sending message notifications ... "); + _log.debug("Sending message notifications ... site server URL= " + site.getSiteURL()); List recipients = getUsersbyUserId(recipientIds); NotificationsManager nm = new ApplicationNotificationsManager( + site, fakeSession.getScope(), new SocialNetworkingUser(fakeSession.getUsername(), fakeSession.getUserEmailAddress(), fakeSession.getUserFullName(), fakeSession.getUserAvatarId()) ); @@ -298,11 +297,11 @@ public class PeriodicTask implements Runnable { private List getUsersbyUserId(List recipientIds) { List recipients = new ArrayList(); for (String userid : recipientIds) { - com.liferay.portal.model.User user; + GCubeUser user; try { - user = UserLocalServiceUtil.getUserByScreenName(OrganizationsUtil.getCompany().getCompanyId(), userid); - recipients.add(new GenericItemBean(""+user.getUserId(), user.getScreenName(), user.getFullName(), "")); - } catch (PortalException | SystemException e) { + user = new LiferayUserManager().getUserByUsername(userid); + recipients.add(new GenericItemBean(""+user.getUserId(), user.getUsername(), user.getFullname(), "")); + } catch (Exception e) { e.printStackTrace(); } } @@ -320,7 +319,7 @@ public class PeriodicTask implements Runnable { private void handlePostReply(String portalName, String feedId, Message message, ASLSession fakeSession) throws Exception { String commentText = extractText(portalName, feedId, message); _log.info("Extracted id: " + feedId + " text=" + commentText); - String escapedCommentText = Utils.escapeHtmlAndTransformUrl(commentText); + String escapedCommentText = org.gcube.portal.socialmail.Utils.escapeHtmlAndTransformUrl(commentText); String subject = message.getSubject(); if (escapedCommentText.trim().compareTo("") == 0) {//it is a favorite/subscription @@ -377,6 +376,7 @@ public class PeriodicTask implements Runnable { boolean isAppFeed = feed.isApplicationFeed(); NotificationsManager nm = new ApplicationNotificationsManager( + site, fakeSession.getScope(), new SocialNetworkingUser(fakeSession.getUsername(), fakeSession.getUserEmailAddress(), fakeSession.getUserFullName(), fakeSession.getUserAvatarId()) ); @@ -407,6 +407,7 @@ public class PeriodicTask implements Runnable { //if the user who commented this post is not the user who posted it notifies the poster user (Feed owner) NotificationsManager nm = new ApplicationNotificationsManager( + site, fakeSession.getScope(), new SocialNetworkingUser(fakeSession.getUsername(), fakeSession.getUserEmailAddress(), fakeSession.getUserFullName(), fakeSession.getUserAvatarId()) ); @@ -473,7 +474,7 @@ public class PeriodicTask implements Runnable { try { messageContent = message.getContent(); String toParse = null; - final String SEPARATOR = EmailPlugin.WRITE_ABOVE_TO_REPLY.substring(0, 23); + final String SEPARATOR = SocialMailingUtil.WRITE_ABOVE_TO_REPLY.substring(0, 23); // Check if content is pure text/html or in parts if (messageContent instanceof Multipart) { _log.debug("Checking if isValidReply, found Multipart Message, getting text part ... looking for separator " + SEPARATOR); @@ -512,7 +513,7 @@ public class PeriodicTask implements Runnable { private static String extractText(String portalName, String subjectId, Message message) throws Exception { Object messageContent = message.getContent(); String toParse = null; - final String SEPARATOR = EmailPlugin.WRITE_ABOVE_TO_REPLY.substring(0, 23); + final String SEPARATOR = SocialMailingUtil.WRITE_ABOVE_TO_REPLY.substring(0, 23); // Check if content is pure text/html or in parts if (messageContent instanceof Multipart) { _log.debug("Found Multipart Message, getting text part ... looking for separator " + SEPARATOR); diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 9663548..d959557 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,8 +1,9 @@ - + + - Email Comments Reader Webapp