Compare commits

..

No commits in common. "master" and "Feature/21689" have entirely different histories.

7 changed files with 72 additions and 197 deletions

1
.gitignore vendored
View File

@ -1,2 +1 @@
/target/
/deploy.sh

View File

@ -1,19 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="social-mail-servlet">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="social-mail-servlet"/>
<property name="java-output-path" value="/social-mail-servlet/target/classes"/>
</wb-module>
</project-modules>

View File

@ -4,11 +4,7 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v3.0.0] - 2024-04-18
- Removed social networking lib dep
## [v2.5.0] - 2021-06-22
## [v2.5.0-SNAPSHOT] - 2021-06-22
- Feature #21689 Social Mail Servlet to StorageHub migration

View File

@ -32,11 +32,18 @@ See [Releases](https://code-repo.d4science.org/gCubeSystem/oauth-service/release
This project is licensed under the EUPL V.1.1 License - see the [LICENSE.md](LICENSE.md) file for details.
## About the gCube Framework
This software is part of the [gCubeFramework](https://www.gcube-system.org/ "gCubeFramework"): an
open-source software toolkit used for building and operating Data
open-source software toolkit used for building and operating Hybrid Data
Infrastructures enabling the dynamic deployment of Virtual Research Environments
by favouring the realisation of reuse oriented policies.
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)
The projects leading to this software have received funding from a series of European Union programmes including:
- the Sixth Framework Programme for Research and Technological Development
- DILIGENT (grant no. 004260);
- the Seventh Framework Programme for research, technological development and demonstration
- D4Science (grant no. 212488), D4Science-II (grant no.239019), ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine(grant no. 283644);
- the H2020 research and innovation programme
- BlueBRIDGE (grant no. 675680), EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant no. 654119), SoBigData (grant no. 654024),DESIRA (grant no. 818194), ARIADNEplus (grant no. 823914), RISIS2 (grant no. 824091), PerformFish (grant no. 727610), AGINFRAplus (grant no. 731001);

37
pom.xml
View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.gcube.tools</groupId>
<artifactId>maven-parent</artifactId>
<version>1.2.0</version>
<version>1.1.0</version>
<relativePath />
</parent>
@ -12,7 +12,7 @@
<groupId>org.gcube.portal</groupId>
<artifactId>social-mail-servlet</artifactId>
<packaging>war</packaging>
<version>3.0.0</version>
<version>2.5.0-SNAPSHOT</version>
<scm>
<connection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
<developerConnection>scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
@ -37,7 +37,7 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>maven-portal-bom</artifactId>
<version>3.7.0</version>
<version>3.6.2-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -71,22 +71,15 @@
<artifactId>aslsocial</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-client-library</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.portal</groupId>
<artifactId>social-networking-library</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.social-networking</groupId>
<artifactId>social-service-client</artifactId>
<version>[2.0.0-SNAPSHOT, 3.0.0)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
@ -116,13 +109,7 @@
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<artifactId>javax.mail</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
@ -177,6 +164,14 @@
<webappDirectory>${webappDirectory}</webappDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>

View File

@ -17,7 +17,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.gcube.application.framework.core.session.SessionManager;
import org.gcube.common.encryption.StringEncrypter;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.resources.gcore.ServiceEndpoint;
@ -55,9 +54,6 @@ public class PortalSchedulerService extends HttpServlet {
private static DatabookStore store;
public void init() {
PortalContext context = PortalContext.getConfiguration();
String scope = "/" + context.getInfrastructureName();
ScopeProvider.instance.set(scope);
store = new DBCassandraAstyanaxImpl();
}
@ -81,7 +77,7 @@ public class PortalSchedulerService extends HttpServlet {
pop3Scheduler.scheduleAtFixedRate(new PeriodicTask(store, popAccount, request), 0, pollingInterval, TimeUnit.MINUTES);
String portalName = "unknown";
try {
portalName = popAccount.getPortalName() ;
popAccount.getPortalName() ;
}
catch (NullPointerException e){
_log.warn("Could not read popAccount data portal name", e);

View File

@ -2,18 +2,26 @@ package org.gcube.portal.socialmail;
import static org.gcube.common.authorization.client.Constants.authorizationService;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
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.apache.commons.lang3.StringEscapeUtils;
@ -26,11 +34,12 @@ import org.gcube.applicationsupportlayer.social.mailing.AppType;
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.authorization.library.provider.AccessTokenProvider;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.provider.UserInfo;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.storagehub.client.plugins.AbstractPlugin;
import org.gcube.common.storagehub.client.proxies.MessageManagerClient;
import org.gcube.portal.databook.server.DatabookStore;
import org.gcube.portal.databook.shared.Comment;
import org.gcube.portal.databook.shared.Feed;
@ -43,35 +52,14 @@ 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.social_networking.social_networking_client_library.MessageClient;
import org.gcube.social_networking.socialnetworking.model.beans.MessageInbox;
import org.gcube.social_networking.socialnetworking.model.beans.MessageInputBean;
import org.gcube.social_networking.socialnetworking.model.beans.Recipient;
import org.gcube.vomanagement.usermanagement.UserManager;
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.sun.mail.util.MailSSLSocketFactory;
import jakarta.mail.Address;
import jakarta.mail.BodyPart;
import jakarta.mail.Flags;
import jakarta.mail.Folder;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.Multipart;
import jakarta.mail.NoSuchProviderException;
import jakarta.mail.Session;
import jakarta.mail.Store;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage.RecipientType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
/**
*
* @author Massimiliano Assante, CNR-ISTI
@ -80,7 +68,6 @@ import okhttp3.ResponseBody;
public class PeriodicTask implements Runnable {
private static final Log _log = LogFactoryUtil.getLog(PeriodicTask.class);
private static final String APP_ID_NEWSFEED = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl";
private static final String SHUB_MESSAGES_ENDPOINT = "workspace/messages/";
private DatabookStore socialStore;
private EmailPopAccount popAccount;
@ -147,20 +134,6 @@ public class PeriodicTask implements Runnable {
}
return toReturn;
}
private static String generateAuthorizationToken(String username, String scope) {
List<String> userRoles = new ArrayList<>();
userRoles.add(DEFAULT_ROLE);
String token;
try {
token = authorizationService().generateUserToken(new UserInfo(username, userRoles), scope);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return token;
}
private final static String DEFAULT_ROLE = "OrganizationMember";
private static void setAuthorizationToken(ASLSession session) throws Exception {
@ -275,16 +248,6 @@ public class PeriodicTask implements Runnable {
* @throws Exception
*/
private void handleMessageReply(String portalName, String messageId, Message message, ASLSession fakeSession) {
String legacyToken = SecurityTokenProvider.instance.get();
_log.info("*****username=" + fakeSession.getUsername());
_log.info("*****context=" + fakeSession.getScope());
legacyToken = generateAuthorizationToken(fakeSession.getUsername(), fakeSession.getScope());
SecurityTokenProvider.instance.set(legacyToken);
String subject = "";
String messageText = "";
try {
@ -296,50 +259,39 @@ public class PeriodicTask implements Runnable {
_log.debug("Found message reply, subject: " + subject + " body: " + messageText);
String newMessageId = null;
ArrayList<String> recipientIds = new ArrayList<String>();
List<String> recipientIds = new ArrayList<>();
try {
String username = fakeSession.getUsername();
String context = fakeSession.getScope();
ScopeProvider.instance.set(context);
_log.debug("calling service token on context " + context);
String scope = fakeSession.getScope();
ScopeProvider.instance.set(scope);
_log.debug("calling service token on scope " + scope);
List<String> userRoles = new ArrayList<>();
userRoles.add(DEFAULT_ROLE);
fakeSession.setSecurityToken(null);
String token = authorizationService().generateUserToken(new UserInfo(username, userRoles), context);
String token = authorizationService().generateUserToken(new UserInfo(username, userRoles), scope);
SecurityTokenProvider.instance.set(token);
MessageInbox theMessage = null;
_log.info("Looking for Message with id "+ messageId);
String messagesEndpoint = getStorageHubURLFromContext(context)+SHUB_MESSAGES_ENDPOINT;
theMessage = getMessageWSById(messagesEndpoint, messageId, token);
_log.info("Got Message = " + theMessage.toString());
if (theMessage != null) {
String[] addresses = theMessage.getAddresses();
for (int i = 0; i < addresses.length; i++) {
recipientIds.add(addresses[i]);
}
//add the sender and remove the person who is replying from the recipients
String sender = theMessage.getSender().getUserName();
String originalText = theMessage.getBody();
Date originalSentTime = theMessage.getCreationTime().getTime();
recipientIds.add(sender);
recipientIds.remove(fakeSession.getUsername());
MessageManagerClient mmClient = AbstractPlugin.messages().build();
org.gcube.common.storagehub.model.messages.Message theMessage = mmClient.get(messageId);
String[] addresses = theMessage.getAddresses();
for (int i = 0; i < addresses.length; i++) {
recipientIds.add(addresses[i]);
}
//add the sender and remove the person who is replying from the recipients
String sender = theMessage.getSender().getUserName();
String originalText = theMessage.getBody();
Date originalSentTime = theMessage.getCreationTime().getTime();
recipientIds.add(sender);
recipientIds.remove(fakeSession.getUsername());
_log.debug("Message Recipients:");
ArrayList<Recipient> recipients = new ArrayList<Recipient>();
for (String rec : recipientIds) {
recipients.add(new Recipient(rec));
_log.debug(rec);
}
_log.debug("Message Recipients:");
for (String rec : recipientIds) {
_log.debug(rec);
}
_log.debug("Constructing reply message");
messageText += getReplyHeaderMessage(sender, originalSentTime, originalText);
_log.debug("Constructing reply message");
messageText += getReplyHeaderMessage(sender, originalSentTime, originalText);
_log.debug("Trying to send message with subject: " + subject + " to: " + recipientIds.toString());
MessageInputBean message2Send = new MessageInputBean(messageText, subject, recipients);
MessageClient messagesClient = new MessageClient();
newMessageId = messagesClient.writeMessage(message2Send);
}
_log.debug("Trying to send message with subject: " + subject + " to: " + recipientIds.toString());
newMessageId = mmClient.sendMessage(recipientIds, subject, messageText, new ArrayList<String>());
} catch (Exception e) {
e.printStackTrace();
@ -363,48 +315,6 @@ public class PeriodicTask implements Runnable {
}
}
/**
* temporary method that get the URL of the Shub based on the context
* @param context
* @return the url
*/
private String getStorageHubURLFromContext(String context) {
String toReturn = "";
if (context.startsWith("/d4science")) {
toReturn = "https://api.d4science.org/";
} else if (context.startsWith("/gcube")) {
toReturn = "https://api.dev.d4science.org/";
} else {
toReturn = "https://api.pre.d4science.org/";
}
return toReturn;
}
/**
* read a message from shub given the id
* @param urlString
* @param token
* @return
* @throws IOException
*/
private static MessageInbox getMessageWSById(String uri, String messageId, String token) throws IOException {
String urlString = uri+messageId;
_log.info("***** getMessageWSById urlString = " + urlString);
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url(urlString)
.addHeader("gcube-token", token)
.build();
ResponseBody responseBody = client.newCall(request).execute().body();
String json = responseBody.string();
_log.info("***** getMessageWSById Response = " + json);
ObjectMapper objectMapper = new ObjectMapper();
MessageInbox theMessage = objectMapper.readValue(json, MessageInbox.class);
return theMessage;
}
private String getReplyHeaderMessage(String senderId, Date date, String message) {
List<String> toPass = new ArrayList<String>();
toPass.add(senderId);
@ -445,15 +355,6 @@ public class PeriodicTask implements Runnable {
* @throws Exception
*/
private void handlePostReply(String portalName, String postId, Message message, ASLSession fakeSession) throws Exception {
String token = AccessTokenProvider.instance.get();
String legacyToken = SecurityTokenProvider.instance.get();
_log.info("*****username=" + fakeSession.getUsername());
_log.info("*****context=" + fakeSession.getScope());
legacyToken = generateAuthorizationToken(fakeSession.getUsername(), fakeSession.getScope());
SecurityTokenProvider.instance.set(legacyToken);
String commentText = extractText(portalName, postId, message);
_log.info("Extracted id: " + postId + " text=" + commentText);
String escapedCommentText = org.gcube.portal.socialmail.Utils.escapeHtmlAndTransformUrl(commentText);
@ -464,7 +365,6 @@ public class PeriodicTask implements Runnable {
likePost(postId, fakeSession);
}
else {
Comment comment = new Comment(UUID.randomUUID().toString(), fakeSession.getUsername(),
new Date(), postId, escapedCommentText, fakeSession.getUserFullName(), fakeSession.getUserAvatarId());
@ -490,21 +390,12 @@ public class PeriodicTask implements Runnable {
* @param fakeSession
*/
private void likePost(String postId, ASLSession fakeSession) {
String token = AccessTokenProvider.instance.get();
String legacyToken = SecurityTokenProvider.instance.get();
_log.info("*****username=" + fakeSession.getUsername());
_log.info("*****context=" + fakeSession.getScope());
legacyToken = generateAuthorizationToken(fakeSession.getUsername(), fakeSession.getScope());
SecurityTokenProvider.instance.set(legacyToken);
if (postId == null || postId.compareTo("") == 0) {
_log.warn("Found email with no feedId from " + fakeSession.getUserEmailAddress() + ". Going to trash it");
return;
}
Like like = new Like(UUID.randomUUID().toString(), fakeSession.getUsername(),
new Date(), postId, fakeSession.getUserFullName(), fakeSession.getUserAvatarId());
@ -524,7 +415,7 @@ public class PeriodicTask implements Runnable {
NotificationsManager nm = new ApplicationNotificationsManager(
site,
post.getVreid(),
fakeSession.getScope(),
new SocialNetworkingUser(fakeSession.getUsername(), fakeSession.getUserEmailAddress(), fakeSession.getUserFullName(), fakeSession.getUserAvatarId()),
APP_ID_NEWSFEED
);
@ -715,7 +606,7 @@ public class PeriodicTask implements Runnable {
sb.append("\n");
}
String toReturn = sb.toString().trim();
//check if the reply is from iOS which add illegal character
String sanytisedLine = StringEscapeUtils.escapeJava(toReturn);
@ -728,6 +619,6 @@ public class PeriodicTask implements Runnable {
return toReturn;
}
}