package org.gcube.portets.user.message_conversations.server; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.NotificationsManager; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.storagehub.client.dsl.FileContainer; import org.gcube.common.storagehub.client.dsl.StorageHubClient; import org.gcube.common.storagehub.client.plugins.AbstractPlugin; import org.gcube.common.storagehub.client.proxies.MessageManagerClient; import org.gcube.common.storagehub.model.items.FolderItem; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.messages.Message; import org.gcube.portal.notifications.bean.GenericItemBean; import org.gcube.portal.notifications.thread.MessageNotificationsThread; import org.gcube.portets.user.message_conversations.client.MessageService; import org.gcube.portets.user.message_conversations.shared.ConvMessage; import org.gcube.portets.user.message_conversations.shared.CurrUserAndPortalUsersWrapper; import org.gcube.portets.user.message_conversations.shared.FileModel; import org.gcube.portets.user.message_conversations.shared.MessageUserModel; import org.gcube.portets.user.message_conversations.shared.WSUser; import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vomanagement.usermanagement.util.ManagementUtils; 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.GroupLocalServiceUtil; import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.util.PortalUtil; /** * @author Massimiliano Assante, CNR-ISTI */ public class ConvServiceImpl implements MessageService { private static final Logger _log = LoggerFactory.getLogger(ConvServiceImpl.class); private PortalContext pContext; private UserManager um; private HttpServletRetriever requestRetriever; ConvServiceImpl(HttpServletRetriever servletRetriever) { um = new LiferayUserManager(); pContext = PortalContext.getConfiguration(); requestRetriever= servletRetriever; } /** * * @return true if you're running into the portal, false if in development */ private boolean isWithinPortal() { try { UserLocalServiceUtil.getService(); return true; } catch (com.liferay.portal.kernel.bean.BeanLocatorException ex) { _log.trace("Development Mode ON"); return false; } } private GCubeUser getCurrentUser(HttpServletRequest httpServletRequest) { if (isWithinPortal()) { try { long userId = PortalUtil.getUser(httpServletRequest).getUserId(); long groupId = pContext.getCurrentGroupId(httpServletRequest); if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) return um.getUserById(userId); else { _log.error("User not authorised in Group, the logged user id=" + userId + " does not belong to group " + groupId); return null; } } catch (Exception e) { _log.warn("Could not read user from LR PortalUtil in delegate servlet"); return null; } } else { return pContext.getCurrentUser(requestRetriever.getRequest()); } } @Override public ArrayList getMessages(boolean sent) { ArrayList toReturn = new ArrayList<>(); try { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); pContext = PortalContext.getConfiguration(); _log.debug("*** Reading user = " +user.getFullname()); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); ScopeProvider.instance.set(scope); String token = pContext.getCurrentUserToken(scope, user.getUserId()); SecurityTokenProvider.instance.set(token); MessageManagerClient client = AbstractPlugin.messages().build(); long start = System.currentTimeMillis(); List listMessages = (sent) ? client.getSentMessages(79) : client.getReceivedMessages(79); if (listMessages == null) { _log.error("listMessages is null, Could not read messages of {}", user.getFullname()); return null; } _log.debug("Got messages of {} how many? {} in {} ms", new Object[] {user.getFullname(), listMessages.size(), (System.currentTimeMillis()-start)}); //the messages from shub are returned ordered from the new one to the oldest, so we don't need to reverse them anymore //Collections.reverse(listMessages); LiferayUserManager um = new LiferayUserManager(); for (Message m : listMessages) { String previewBody = m.getBody() + " ..."; MessageUserModel mu = null; GCubeUser sender = null; try { if (sent) { if (m.getAddresses().length < 2) { GCubeUser recipient = um.getUserByUsername(m.getAddresses()[0]); mu = new MessageUserModel(recipient.getUserId(), recipient.getUsername(), recipient.getFullname(), recipient.getUserAvatarURL(), "", ""); } else { //we have at least 2 recipients GCubeUser recipient1 = um.getUserByUsername(m.getAddresses()[0]); GCubeUser recipient2 = um.getUserByUsername(m.getAddresses()[1]); String label2Display = recipient1.getFirstName() + " & " + recipient2.getFirstName(); if (m.getAddresses().length > 2) label2Display += " & ..."; mu = new MessageUserModel(recipient1.getUserId(), recipient1.getUsername(), label2Display, null, "", ""); } } else { //received message sender = um.getUserByUsername(m.getSender().getUserName()); mu = new MessageUserModel(sender.getUserId(), sender.getUsername(), sender.getFullname(), sender.getUserAvatarURL(), "", ""); } } catch (Exception ex) { ex.printStackTrace(); if (!sent) { mu = new MessageUserModel(m.getSender().getUserName()); } else { mu = new MessageUserModel(m.getAddresses()[0]); } } boolean hasAttachments = m.isWithAttachments(); if (!sent) { //received messages toReturn.add(new ConvMessage( m.getId(), m.getSubject(), mu, new Date(m.getCreationTime().getTimeInMillis()), previewBody, m.isRead(), hasAttachments)); } else { //sent messages ArrayList recipients = new ArrayList<>(); for (String rec : m.getAddresses()) { recipients.add(new MessageUserModel(rec)); } toReturn.add(new ConvMessage( m.getId(), m.getSubject(), mu, recipients, new Date(m.getCreationTime().getTimeInMillis()), previewBody, m.isRead(), hasAttachments)); } } } catch (Exception e) { e.printStackTrace(); return null; } _log.trace("get All Messages Received "); return toReturn; } @Override public boolean markMessageUnread(String messageId, boolean sent) { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); SecurityTokenProvider.instance.set(pContext.getCurrentUserToken(scope, user.getUserId())); try { MessageManagerClient client = AbstractPlugin.messages().build(); client.setRead(messageId, false); return true; } catch (Exception e) { e.printStackTrace(); return false; } } @Override public ConvMessage getMessageById(String messageId, boolean sent) { ConvMessage toReturn = null; try { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); _log.debug("*** Reading user from liferay session = " +user.getFullname()); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); SecurityTokenProvider.instance.set(pContext.getCurrentUserToken(scope, user.getUserId())); LiferayUserManager um = new LiferayUserManager(); MessageManagerClient client = AbstractPlugin.messages().build(); Message m= client.get(messageId); MessageUserModel mu = null; GCubeUser sender = null; try { sender = um.getUserByUsername(m.getSender().getUserName()); mu = new MessageUserModel(sender.getUserId(), sender.getUsername(), sender.getFullname(), extractDomainFromEmail(sender.getEmail())); } catch (Exception ex) { mu = new MessageUserModel(m.getSender().getUserName()); } ArrayList recipients = new ArrayList<>(); for (String recipient : m.getAddresses()) { try { GCubeUser toAdd = um.getUserByUsername(recipient); recipients.add(new MessageUserModel(toAdd.getUserId(), toAdd.getUsername(), toAdd.getFullname(), extractDomainFromEmail(toAdd.getEmail()))); } catch (Exception ex) { recipients.add(new MessageUserModel(recipient)); } } ArrayList attachments = new ArrayList<>(); List attachItems = client.getAttachments(messageId); for (Item item : attachItems) { String downloadURL = null; //removed for performanc issue and done on demand attachments.add(new FileModel(item.getId(), item.getName(), null, item instanceof FolderItem, downloadURL)); } boolean hasAttachments = !attachItems.isEmpty(); toReturn = new ConvMessage( m.getId(), m.getSubject(), mu, recipients, new Date(m.getCreationTime().getTimeInMillis()), m.getBody(), m.isRead(), attachments, hasAttachments); //TODO: update this if (!sent) { m.setRead(true); //marked as rea */ client.setRead(messageId, true); } } catch (Exception e) { e.printStackTrace(); } return toReturn; } @Override public String getAttachmentDownloadURL(String itemId) { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); SecurityTokenProvider.instance.set(pContext.getCurrentUserToken(scope, user.getUserId())); _log.info("getAttachmentDownloadURL for user "+user.getUsername() + " file id="+itemId); try { StorageHubClient shc = new StorageHubClient(); String downladURL = shc.open(itemId).asFile().getPublicLink().toString(); downladURL = (downladURL.startsWith("https")) ? downladURL : downladURL.replace("http", "https"); return downladURL; } catch (Exception e) { e.printStackTrace(); return null; } } @Override public boolean saveAttachmentToWorkspaceFolder(String itemId, String destinationFolderId) { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); SecurityTokenProvider.instance.set(pContext.getCurrentUserToken(scope, user.getUserId())); try { StorageHubClient shc = new StorageHubClient(); FileContainer fileContainer = shc.open(itemId).asFile(); FileContainer copiedFile = fileContainer.copy(shc.open(destinationFolderId).asFolder(), fileContainer.get().getTitle()); return (copiedFile.get() != null); } catch (Exception e) { e.printStackTrace(); return false; } } @Override public boolean deleteMessageById(String messageId, boolean sent) { GCubeUser user = getCurrentUser(requestRetriever.getRequest()); _log.debug("deleteMessageById reading user from liferay session = " +user.getFullname() + " m id = " + messageId); String scope = pContext.getCurrentScope(requestRetriever.getRequest()); SecurityTokenProvider.instance.set(pContext.getCurrentUserToken(scope, user.getUserId())); try { MessageManagerClient client = AbstractPlugin.messages().build(); client.delete(messageId); } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override public ArrayList searchUsers(String keyword) { ArrayList toReturn = new ArrayList<>(); if (isWithinPortal()) { long gatewayGroupId = pContext.getCurrentGroupId(this.requestRetriever.getRequest()); try { _log.debug("Searching " + keyword); List users = um.searchUsersByGroup(keyword, gatewayGroupId); for (GCubeUser user : users) { toReturn.add(new WSUser(""+user.getUserId(), user.getUsername(), user.getFullname(), extractDomainFromEmail(user.getEmail()))); } } catch (Exception e) { e.printStackTrace(); } } else { //development for (int i = 0; i < 10; i++) { toReturn.add(new WSUser("andrea.rossi", "andrea.rossi", "Andrea Rossi", "m.assante@gmail.com")); if (i % 2 == 0) toReturn.add(new WSUser(""+i, "username"+i, "userGetFullname()"+i, "user.getEmail()"+i)); else toReturn.add(new WSUser(""+i, "ciccio"+i, "ciccioNome"+i, "ciccioEMail"+i)); } } return toReturn; } @Override public ArrayList getUsersInfo(String[] usernames) { ArrayList toReturn = new ArrayList<>(); if (isWithinPortal()) { try { for (String username : usernames) { User user = UserLocalServiceUtil.getUserByScreenName(ManagementUtils.getCompany().getCompanyId(), username); toReturn.add(new WSUser(""+user.getUserId(), user.getScreenName(), user.getFullName(), extractDomainFromEmail(user.getEmailAddress()))); } } catch (SystemException | PortalException e) { e.printStackTrace(); } } else { //development toReturn.add(new WSUser("andrea.rossi", "andrea.rossi", "Andrea Rossi", "rossi@gmail.com")); toReturn.add(new WSUser("ginoi", "gino", "Gino Pino", "gino@hotmail.com")); } return toReturn; } @Override public boolean sendToById(ArrayList recipientIds, ArrayList listAttachmentsId, String subject, String body) { PortalContext pContext = PortalContext.getConfiguration(); GCubeUser currentUser = pContext.getCurrentUser(requestRetriever.getRequest()); MessageManagerClient client = AbstractPlugin.messages().build(); try { _log.info("Sending message to: " + recipientIds.toString()); String checkedSubject = subject; String checkedBody = body; String messageId = client.sendMessage(recipientIds, checkedSubject, checkedBody, listAttachmentsId); /*try { body += getPublicLinksForAttachs(listAttachmentsId); catch (StorageHubException e) { _log.error("Ops, could not generate publick link for some of the attachments"); }*/ _log.debug("Sending message notification to: " + recipientIds.toString()); List recipients = getUsersbyUserId(recipientIds); NotificationsManager nm = new ApplicationNotificationsManager(new SocialNetworkingSite(requestRetriever.getRequest()), pContext.getCurrentScope(requestRetriever.getRequest()), new SocialNetworkingUser( currentUser.getUsername(), currentUser.getEmail(), currentUser.getFullname(), currentUser.getUserAvatarURL() )); Thread thread = new Thread(new MessageNotificationsThread(recipients, messageId, checkedSubject, body, nm)); thread.start(); return true; } catch (Exception e) { _log.error("While Sending message to: " + recipientIds.toString()); e.printStackTrace(); return false; } } /** * utility method extract the @domain.com from an email address * return @unknown-domain in case of no emails */ private String extractDomainFromEmail(String email) { int index = email.indexOf('@'); if (index > 0) return email.substring(index); else return "@unknown-domain"; } /** * return the User instance given his id * @param recipientIds * @return */ private List getUsersbyUserId(List recipientIds) { List recipients = new ArrayList(); for (String userid : recipientIds) { GCubeUser user = null; try { user = new LiferayUserManager().getUserByUsername(userid); recipients.add(new GenericItemBean(""+user.getUserId(), user.getUsername(), user.getFullname(), "")); } catch (Exception e) { e.printStackTrace(); } } return recipients; } /** * * @param workspace * @param listAttachmentsId * @return * @throws ItemNotFoundException * @throws InternalErrorException */ /* private String getPublicLinksForAttachs(ArrayList listAttachments) { if (listAttachments != null && (!listAttachments.isEmpty()) ) { StorageHubClient client = new StorageHubClient(); StringBuilder builder = new StringBuilder(); builder.append("\n\n\nThe following "); String msg = listAttachments.size()>1?"files were attached to this message:":"file was attached to this message:"; builder.append(msg+"\n"); for (String itemId : listAttachments) { try { OpenResolver openResolver = client.open(itemId); if(openResolver.asItem().getType()==ContainerType.FOLDER) { String publicLink = openResolver.getPublickLink(itemId).toString();; String itemName = item.getTitle(); builder.append(itemName + " ("+publicLink+")"); builder.append("\n"); }catch (StorageHubException e) { _log.error("While reading attachments"); e.printStackTrace(); } } } _log.debug("returning public links: "+builder.toString()); return builder.toString(); } else return ""; }*/ /** * * @return the list of workspace users */ @Override public CurrUserAndPortalUsersWrapper getWorkspaceUsers() { PortalContext pContext = PortalContext.getConfiguration(); GCubeUser currentUser = pContext.getCurrentUser(requestRetriever.getRequest()); _log.debug("trying to get WorkspaceUsers .."); WSUser currUser = null; ArrayList portalUsers = new ArrayList(); try { if (isWithinPortal()) { UserManager um = new LiferayUserManager(); GroupManager gm = new LiferayGroupManager(); List users = um.listUsersByGroup(gm.getRootVO().getGroupId()); for (GCubeUser user : users) { _log.trace("Trying to get additional info for "+user.getUsername()); portalUsers.add(new WSUser(user.getUserId()+"", user.getUsername(), user.getFullname(), user.getEmail())); } } else { for (int i = 0; i < 10; i++) { portalUsers.add(new WSUser(""+i, "username"+i, "userGetFullname()"+i, "user.getEmail()"+i)); } } currUser = new WSUser(currentUser.getUsername(), currentUser.getUsername(), currentUser.getFullname(), currentUser.getEmail()); } catch (Exception e) { _log.error("Error in server get all contacts ", e); } CurrUserAndPortalUsersWrapper toReturn = new CurrUserAndPortalUsersWrapper(currUser, portalUsers); return toReturn; } }