diff --git a/.classpath b/.classpath index b5b3789..b96f5b8 100644 --- a/.classpath +++ b/.classpath @@ -18,9 +18,9 @@ - + - + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 69c31cd..443e085 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,8 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index c78d932..4f92af5 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/pom.xml b/pom.xml index a845bcb..ecbee23 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.common.portal portal-manager - 2.0.0-SNAPSHOT + 2.1.0-SNAPSHOT jar gCube Portal Manager @@ -41,14 +41,26 @@ + + org.gcube.portal + client-context-library + [1.0.0-SNAPSHOT,) + org.gcube.dvos usermanagement-core + + org.gcube.common + authorization-client + + + org.gcube.common + common-authorization + javax.servlet - servlet-api - 2.4 + javax.servlet-api provided @@ -106,8 +118,8 @@ maven-compiler-plugin 3.0 - 1.6 - 1.6 + 1.7 + 1.7 diff --git a/src/main/java/org/gcube/common/portal/PortalContext.java b/src/main/java/org/gcube/common/portal/PortalContext.java index ee20889..e44a593 100644 --- a/src/main/java/org/gcube/common/portal/PortalContext.java +++ b/src/main/java/org/gcube/common/portal/PortalContext.java @@ -1,5 +1,7 @@ package org.gcube.common.portal; +import static org.gcube.common.authorization.client.Constants.authorizationService; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -9,17 +11,22 @@ import java.util.Properties; import javax.servlet.http.HttpServletRequest; +import org.gcube.common.authorization.library.provider.UserInfo; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portal.clientcontext.client.GCubeClientContext; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; +import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.CustomAttributeKeys; +import org.gcube.vomanagement.usermanagement.model.Email; +import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.liferay.portal.kernel.util.StringBundler; -import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.model.Group; import com.liferay.portal.model.VirtualHost; import com.liferay.portal.service.CompanyLocalServiceUtil; import com.liferay.portal.service.LayoutSetLocalServiceUtil; +import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.service.VirtualHostLocalServiceUtil; import com.liferay.portal.util.PortalUtil; @@ -36,6 +43,27 @@ import com.liferay.portal.util.PortalUtil; public class PortalContext { private static final Logger _log = LoggerFactory.getLogger(PortalContext.class); + /** + * Scope separators used in linear syntax. + */ + protected static final String SCOPE_SEPARATOR = "/"; + + private final static String DEFAULT_ROLE = "OrganizationMember"; + + private static final String CONFIGURATION_FOLDER = "conf"; + private static final String INFRA_PROPERTY_FILENAME = "infrastructure.properties"; + private static final String GCUBE_DEV__CONTEXT_PROPERTY_FILENAME = "gcube-dev-context.properties"; + + private static final String DEV_USERNAME_ATTR = "user.username"; + private static final String DEV_USER_NAME_ATTR = "user.name"; + private static final String DEV_USER_LASTNAME_ATTR = "user.lastname"; + private static final String DEV_USER_EMAIL_ATTR = "user.email"; + + private static final String DEV_SCOPE_ATTR = "development.scope"; + private static final String DEV_TOKEN_ATTR = "user.token"; + + + private static final String DEFAULT_INFRA_NAME = "gcube"; private static final String DEFAULT_VO_NAME = "devsec"; private static final String DEFAULT_GATEWAY_NAME = "D4science Gateway"; @@ -60,7 +88,12 @@ public class PortalContext { private void initialize() { Properties props = new Properties(); try { - String propertyfile = getCatalinaHome() + File.separator + "conf" + File.separator + "infrastructure.properties"; + StringBuilder sb = new StringBuilder(getCatalinaHome()); + sb.append(File.separator) + .append(CONFIGURATION_FOLDER) + .append(File.separator) + .append(INFRA_PROPERTY_FILENAME); + String propertyfile = sb.toString(); File propsFile = new File(propertyfile); FileInputStream fis = new FileInputStream(propsFile); props.load( fis); @@ -72,8 +105,10 @@ public class PortalContext { vos = DEFAULT_VO_NAME; _log.error("infrastructure.properties file not found under $CATALINA_HOME/conf/ dir, setting default infrastructure Name " + infra + " and VO Name " + vos); } + _log.info("PortalContext configurator correctly initialized on " + infra); } + /** * * @return the infrastructure name in which your client runs @@ -88,6 +123,134 @@ public class PortalContext { public String getVOsAsString() { return this.vos; } + /** + * + * @param httpServletRequest the httpServletRequest object + * @return the instance of the user + * @see GCubeUser + */ + public GCubeUser getCurrentUser(HttpServletRequest httpServletRequest) { + String userIdNo = httpServletRequest.getHeader(GCubeClientContext.USER_ID_ATTR_NAME); + if (userIdNo != null) { + long userId = -1; + try { + userId = Long.parseLong(userIdNo); + return new LiferayUserManager().getUserById(userId); + } catch (NumberFormatException e) { + _log.error("The userId is not a number -> " + userId); + } catch (Exception e) { + _log.error("The userId does not belong to any user -> " + userId); + } + } else { + if (isWithinPortal()) { + _log.error("It seems your app is running in Liferay but not context was set on this (HttpServletRequest) request, " + + "make sure you have set the gCube ClientContext correctly in your code."); + } else { + GCubeUser toReturn = readUserFromPropertyFile(); + _log.debug("getCurrentUser devMode into IDE detected, returning testing user: " + toReturn.toString()); + return toReturn; + } + } + return null; + } + + /** + * + * @param httpServletRequest the httpServletRequest object + * @return the instance of the user + * @see GCubeUser + */ + public String getCurrentScope(HttpServletRequest httpServletRequest) { + String groupIdNo = httpServletRequest.getHeader(GCubeClientContext.VRE_ID_ATTR_NAME); + if (groupIdNo != null) { + long groupId = -1; + try { + groupId = Long.parseLong(groupIdNo); + LiferayGroupManager gm = new LiferayGroupManager(); + if (gm.isRootVO(groupId)) { + return SCOPE_SEPARATOR + getInfrastructureName(); + } else + return new LiferayGroupManager().getInfrastructureScope(groupId); + } catch (NumberFormatException e) { + _log.error("The groupId is not a number -> " + groupId); + } catch (Exception e) { + _log.error("This groupId does not belong to any group in this portal -> " + groupId); + } + } else { + if (isWithinPortal()) { + _log.error("It seems your app is running in Liferay but not context was set on this (HttpServletRequest) request, " + + "make sure you have set the gCube ClientContext correctly in your code."); + } else { + String toReturn = readScopePropertyFile(); + _log.debug("getCurrentScope devMode into IDE detected, returning scope: " + toReturn.toString()); + _log.debug("The PortalBeanLocatorUtil stacktrace (java.lang.Exception) is acceptable in dev"); + return toReturn; + } + } + return null; + } + + /** + * + * @param httpServletRequest the httpServletRequest object + * @return the instance of the user + * @see GCubeUser + */ + public String getCurrentUserToken(HttpServletRequest httpServletRequest) { + String groupIdNo = httpServletRequest.getHeader(GCubeClientContext.VRE_ID_ATTR_NAME); + if (groupIdNo != null) { + String scope = getCurrentScope(httpServletRequest); + String username = getCurrentUser(httpServletRequest).getUsername(); + try { + return getAuthorizationToken(username, scope); + } catch (Exception e) { + _log.error("Error while trying to generate token for user " + username + "in scope " + scope); + e.printStackTrace(); + return null; + } + } else { + if (isWithinPortal()) { + _log.error("It seems your app is running in Liferay but not context was set on this (HttpServletRequest) request, " + + "make sure you have set the gCube ClientContext correctly in your code."); + } else { + String toReturn = readTokenPropertyFile(); + _log.debug("getCurrentToken devMode into IDE detected, returning scope: " + toReturn.toString()); + _log.debug("The PortalBeanLocatorUtil stacktrace (java.lang.Exception) is acceptable in dev"); + return toReturn; + } + } + return null; + } + /** + * + * @param username + * @param scope + * @throws Exception + */ + private static String getAuthorizationToken(String username, String scope) throws Exception { + ScopeProvider.instance.set(scope); + _log.debug("calling service token on scope " + scope); + List userRoles = new ArrayList<>(); + userRoles.add(DEFAULT_ROLE); + String token = authorizationService().generateUserToken(new UserInfo(username, userRoles), scope); + _log.debug("received token: "+token); + return token; + } + /** + * + * @return true if you're running into the portal, false if in development + */ + private boolean isWithinPortal() { + try { + UserLocalServiceUtil.getService(); + return true; + } + catch (Exception ex) { + _log.trace("Development Mode ON"); + return false; + } + } + /** * * @return the value of the scopes @@ -159,11 +322,9 @@ public class PortalContext { * * @param request * @return the landing page path of the current Site e.g. "/group/i-marine" - * @throws PortalException - * @throws SystemException */ public String getSiteLandingPagePath(final HttpServletRequest request) { - String sitePath = StringPool.BLANK; + String sitePath = ""; Group site; try { site = getSiteFromServletRequest(request); @@ -181,11 +342,9 @@ public class PortalContext { * * @param serverName e.g. myportal.mydomain.org * @return the landing page path of the current Site e.g. "/group/i-marine" - * @throws PortalException - * @throws SystemException */ public String getSiteLandingPagePath(final String serverName) { - String sitePath = StringPool.BLANK; + String sitePath = ""; Group site; try { site = getSiteFromServerName(serverName); @@ -203,8 +362,6 @@ public class PortalContext { * * @param request * @return the current Group instance based on the request - * @throws PortalException - * @throws SystemException */ private Group getSiteFromServletRequest(final HttpServletRequest request) throws Exception { String serverName = request.getServerName(); @@ -225,9 +382,7 @@ public class PortalContext { /** * * @param serverName e.g. myportal.mydomain.org - * @return - * @throws PortalException - * @throws SystemException + * @return the Liferay Group instance responding to the servename passed as parameter */ private Group getSiteFromServerName(final String serverName) throws Exception { _log.debug("serverName passed is " + serverName); @@ -252,28 +407,10 @@ public class PortalContext { * @param isPrivate * @param isUser * @return - * @throws PortalException - * @throws SystemException - */ - @Deprecated - private static String getGroupFriendlyURL(HttpServletRequest request, final Group currentGroup) throws Exception { - String friendlyURL = GCubePortalConstants.PREFIX_GROUP_URL; - StringBundler sb = new StringBundler(); - sb.append(friendlyURL).append(currentGroup.getFriendlyURL()); - return sb.toString(); - } - /** - * @param request - * @param currentGroup - * @param isPrivate - * @param isUser - * @return - * @throws PortalException - * @throws SystemException */ private static String getGroupFriendlyURL(final Group currentGroup) throws Exception { String friendlyURL = GCubePortalConstants.PREFIX_GROUP_URL; - StringBundler sb = new StringBundler(); + StringBuffer sb = new StringBuffer(); sb.append(friendlyURL).append(currentGroup.getFriendlyURL()); return sb.toString(); } @@ -368,8 +505,8 @@ public class PortalContext { } return toReturn; } - - + + /** * read the sender (from) email address for notifications name from a property file and returns it * @deprecated use getSenderEmail(HttpServletRequest request) @@ -397,29 +534,88 @@ public class PortalContext { return toReturn; } /** - * use org.gcube.vomanagement.usermanagement.impl.LiferayUserManager#getAdmin method + * for development purposes only */ - @Deprecated - public String getAdministratorUsername() { - //get the portles to look for from the property file + private static GCubeUser readUserFromPropertyFile() { Properties props = new Properties(); - String toReturn = ""; - try { - String propertyfile = getCatalinaHome() + File.separator + "conf" + File.separator + "gcube-data.properties"; + StringBuilder sb = new StringBuilder(getCatalinaHome()); + sb.append(File.separator) + .append(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME); + String propertyfile = sb.toString(); File propsFile = new File(propertyfile); FileInputStream fis = new FileInputStream(propsFile); props.load( fis); - toReturn = props.getProperty(GCubePortalConstants.ADMIN_USERNAME); + long userId = -1; + String username = props.getProperty(DEV_USERNAME_ATTR); + String email = props.getProperty(DEV_USER_EMAIL_ATTR); + String firstName = props.getProperty(DEV_USER_NAME_ATTR); + String middleName = ""; + String lastName = props.getProperty(DEV_USER_LASTNAME_ATTR); + String fullname = firstName + lastName; + long registrationDate = -1; + String userAvatarId = "-1"; + boolean male = true; + String jobTitle = "TestingAccount"; + List emailAddresses = new ArrayList<>(); + + return new GCubeUser(userId, username, email, firstName, middleName, lastName, fullname, registrationDate, userAvatarId, male, jobTitle, emailAddresses); } - //catch exception in case properties file does not exist catch(IOException e) { - toReturn = "massimiliano.assante"; - _log.error("gcube-data.properties file not found under $CATALINA_HOME/conf dir, returning default administrator" + toReturn); - return toReturn; + _log.error(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME + " file not found under $CATALINA_HOME dir"); + return null; + } + } + /** + * for development purposes only + */ + private static String readTokenPropertyFile() { + Properties props = new Properties(); + try { + StringBuilder sb = new StringBuilder(getCatalinaHome()); + sb.append(File.separator) + .append(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME); + String propertyfile = sb.toString(); + File propsFile = new File(propertyfile); + FileInputStream fis = new FileInputStream(propsFile); + props.load( fis); + String token = props.getProperty(DEV_TOKEN_ATTR); + if (token != null && token.compareTo("") != 0) + return token; + else { + _log.error("Token property "+ DEV_TOKEN_ATTR + " is missing or empty in the property file " + propertyfile); + return null; + } } - _log.debug("Returning Administrator username: " + toReturn ); - return toReturn; + catch(IOException e) { + _log.error(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME + " file not found under $CATALINA_HOME dir"); + return null; + } + }/** + * for development purposes only + */ + private static String readScopePropertyFile() { + Properties props = new Properties(); + try { + StringBuilder sb = new StringBuilder(getCatalinaHome()); + sb.append(File.separator) + .append(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME); + String propertyfile = sb.toString(); + File propsFile = new File(propertyfile); + FileInputStream fis = new FileInputStream(propsFile); + props.load( fis); + String scope = props.getProperty(DEV_SCOPE_ATTR); + if (scope.startsWith(SCOPE_SEPARATOR)) + return scope; + else { + _log.error("Scope is not valid, does not start with " + SCOPE_SEPARATOR); + return null; + } + } + catch(IOException e) { + _log.error(GCUBE_DEV__CONTEXT_PROPERTY_FILENAME + " file not found under $CATALINA_HOME dir"); + return null; + } } /** * diff --git a/src/main/java/org/gcube/common/portal/mailing/EmailNotification.java b/src/main/java/org/gcube/common/portal/mailing/EmailNotification.java index fbd1bd3..503562b 100644 --- a/src/main/java/org/gcube/common/portal/mailing/EmailNotification.java +++ b/src/main/java/org/gcube/common/portal/mailing/EmailNotification.java @@ -31,6 +31,7 @@ public class EmailNotification { private String emailrecipients[]; private List emailRecipientsInCC; + private List emailRecipientsInBCC; /** * Email's subject */ @@ -100,6 +101,14 @@ public class EmailNotification { } } + public void addRecipientInBCC(String email) { + try { + emailRecipientsInBCC.add(new InternetAddress(email)); + } catch (AddressException e) { + e.printStackTrace(); + } + } + public void sendEmail() { Properties props = System.getProperties(); props.put("mail.smtp.host", MAIL_SERVICE_HOST); @@ -131,7 +140,10 @@ public class EmailNotification { for (InternetAddress email : emailRecipientsInCC) { mimeMessage.addRecipient(Message.RecipientType.CC, email); } - + // EMAIL BCC Recipients + for (InternetAddress email : emailRecipientsInBCC) { + mimeMessage.addRecipient(Message.RecipientType.BCC, email); + } mimeMessage.setSubject(emailSubject); mimeMessage.setContent(emailBody.toString(), "text/html; charset=UTF-8"); mimeMessage.setSentDate(new Date());