diff --git a/pom.xml b/pom.xml index c0301bb..40dffe7 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.common.portal portal-manager - 2.1.0-SNAPSHOT + 2.2.0-SNAPSHOT jar gCube Portal Manager diff --git a/src/main/java/org/gcube/common/portal/ContextUserUtil.java b/src/main/java/org/gcube/common/portal/ContextUserUtil.java deleted file mode 100644 index 02a07e3..0000000 --- a/src/main/java/org/gcube/common/portal/ContextUserUtil.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.gcube.common.portal; - -import java.io.UnsupportedEncodingException; -import java.security.Key; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.liferay.portal.model.Company; -import com.liferay.portal.service.CompanyLocalServiceUtil; -import com.liferay.portal.service.UserLocalServiceUtil; -import com.liferay.util.Encryptor; -/** - * - * @author Massimiliano Assante, CNR-ISTI - * - */ -public class ContextUserUtil { - private static final Logger _log = LoggerFactory.getLogger(ContextUserUtil.class); - /** - * - * @param httpServletRequest - * @returnthe current user LR id - */ - protected static Long getCurrentUserId(HttpServletRequest httpServletRequest) { - Cookie[] cookies = httpServletRequest.getCookies(); - String userId = null; - String companyId = null; - if (cookies != null) { - for (Cookie c : cookies) { - if ("COMPANY_ID".equals(c.getName())) { - companyId = c.getValue(); - } else if ("ID".equals(c.getName())) { - _log.debug("User id before ascii conversion is " + c.getValue()); - userId = hexStringToStringByAscii(c.getValue()); - } - } - if (userId != null && companyId != null) { - try { - Company company = CompanyLocalServiceUtil.getCompany(Long.parseLong(companyId)); - _log.debug("company is " + company); - Key key = company.getKeyObj(); - _log.debug("key is " + company.getKey()); - _log.debug("User id after ascii conversion is " + userId); - String userIdPlain = Encryptor.decrypt(key, userId); - return Long.valueOf(userIdPlain); - - } catch (Exception pException) { - _log.warn("Exception while getting current user from cookie, returning current user from http header"); - return getUserFromHeader(httpServletRequest); - } - } else { - if (isWithinPortal()) { - _log.debug("Something wrong with cookies, returning current user from http header"); - return getUserFromHeader(httpServletRequest); - } else { //you must be in dev - _log.debug("DEV MODE Intercepted ..."); - return null; - } - } - } else { - _log.warn("Cookies are not present, returning current user from http header"); - return getUserFromHeader(httpServletRequest); - } - } - - private static long getUserFromHeader(HttpServletRequest httpServletRequest) { - String userHeaderIdString = httpServletRequest.getHeader(PortalContext.USER_ID_ATTR_NAME); - long userIdToReturn = -1; - try { - userIdToReturn = Long.parseLong(userHeaderIdString); - } catch (NumberFormatException e) { - _log.error("The userId is not a number -> " + userHeaderIdString); - } - return userIdToReturn; - } - - private static String hexStringToStringByAscii(String hexString) { - byte[] bytes = new byte[hexString.length() / 2]; - for (int i = 0; i < hexString.length() / 2; i++) { - String oneHexa = hexString.substring(i * 2, i * 2 + 2); - bytes[i] = Byte.parseByte(oneHexa, 16); - } - try { - return new String(bytes, "ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - /** - * - * @return true if you're running into the portal, false if in development - */ - private static boolean isWithinPortal() { - try { - UserLocalServiceUtil.getService(); - return true; - } - catch (Exception ex) { - _log.trace("Development Mode ON"); - return false; - } - } -} diff --git a/src/main/java/org/gcube/common/portal/PortalContext.java b/src/main/java/org/gcube/common/portal/PortalContext.java index fbbcedc..1a7e9c7 100644 --- a/src/main/java/org/gcube/common/portal/PortalContext.java +++ b/src/main/java/org/gcube/common/portal/PortalContext.java @@ -15,6 +15,9 @@ import org.gcube.common.authorization.client.exceptions.ObjectNotFound; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.vomanagement.usermanagement.UserManager; +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.CustomAttributeKeys; @@ -35,9 +38,12 @@ import com.liferay.portal.util.PortalUtil; /** + *

* Clients can obtain the single instance of the {@link PortalContext} by invoking its static method {@link #getConfiguration()}. * The first invocation of the method triggers the initialisation of the instance. * + * For documentation see the related WIKI + *

* @author Massimiliano Assante (ISTI-CNR) * */ @@ -75,6 +81,8 @@ public class PortalContext { private static PortalContext singleton = new PortalContext(); + private UserManager userManager; + private String infra; private String vos; @@ -103,6 +111,7 @@ public class PortalContext { props.load( fis); infra = props.getProperty(GCubePortalConstants.INFRASTRUCTURE_NAME); vos = props.getProperty(GCubePortalConstants.SCOPES); + userManager = new LiferayUserManager(); } catch(IOException e) { infra = DEFAULT_INFRA_NAME; @@ -128,23 +137,31 @@ public class PortalContext { return this.vos; } /** + *

+ * Please note that this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). + * If you use standard http servlet GET or POST to exchange data with a server, you must use Liferay's PortalDelegateServlet feature {@link com.liferay.portal.kernel.servlet.PortalDelegateServlet}. * - * @param httpServletRequest the httpServletRequest object - * @return the instance of the current user - * @see GCubeUser + * For documentation on PortalDelegateServlet @see gCube WIKI PortalDelegateServlet page + *

+ * + * @param httpServletRequest the {@link HttpServletRequest} object + * @return the current user, or null if a current user could not be found + * @see {@link GCubeUser} */ public GCubeUser getCurrentUser(HttpServletRequest httpServletRequest) { - Long userIdNo = ContextUserUtil.getCurrentUserId(httpServletRequest); + String userIdNo = httpServletRequest.getHeader(USER_ID_ATTR_NAME); if (userIdNo != null) { + long userId = -1; try { - return new LiferayUserManager().getUserById(userIdNo); - } catch (Exception e) { - _log.error("The userId does not belong to any user -> " + userIdNo); + userId = Long.parseLong(userIdNo); + return userManager.getUserById(userId); + } catch (NumberFormatException e) { + _log.error("The userId is not a number -> " + userId); + } catch (Exception e) { + _log.error("Could not read the current userid, either session expired or user not logged in, exception: " + e.getMessage()); } } else { - if (isWithinPortal()) { - _log.warn("Could not read the current userid, either session expired or user not logged in"); - } else { + if (!isWithinPortal()) { GCubeUser toReturn = readUserFromPropertyFile(); _log.debug("getCurrentUser devMode into IDE detected, returning testing user: " + toReturn.toString()); return toReturn; @@ -153,7 +170,6 @@ public class PortalContext { return null; } /** - * * @param scopeGroupId the liferay groupid number (as String) of the VRE/VO * @return the scope (context) */ @@ -183,19 +199,28 @@ public class PortalContext { return null; } /** + *

+ * Please note that this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). + * If you use standard http servlet GET or POST to exchange data with a server, you must you must handle the infrastructure context information differently. + * Please see the following page for further information @see ClientContextLibrary WIKI + *

* - * @param httpServletRequest the httpServletRequest object - * @return the scope (context) + * @param httpServletRequest the {@link HttpServletRequest} object + * @return the infrastructure context (scope) */ public String getCurrentScope(HttpServletRequest httpServletRequest) { String scopeGroupId = httpServletRequest.getHeader(VRE_ID_ATTR_NAME); return getCurrentScope(scopeGroupId); } /** + *

+ * Please note that this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). + * If you use standard http servlet GET or POST to exchange data with a server, you must you must handle the infrastructure context information differently. + * Please see the following page for further information @see ClientContextLibrary WIKI + *

* - * @param httpServletRequest the httpServletRequest object - * @return the instance of the user - * @see GCubeUser + * @param httpServletRequest the {@link HttpServletRequest} object + * @return the current group name (e.g. devVRE, BioDiversityLab, RStudioLab etc. ) */ public String getCurrentGroupName(HttpServletRequest httpServletRequest) { String groupIdNo = httpServletRequest.getHeader(VRE_ID_ATTR_NAME); @@ -221,10 +246,14 @@ public class PortalContext { return null; } /** + *

+ * Please note that this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). + * If you use standard http servlet GET or POST to exchange data with a server, you must you must handle the infrastructure context information differently. + * Please see the following page for further information @see ClientContextLibrary WIKI + *

* - * @param httpServletRequest the httpServletRequest object - * @return the instance of the user - * @see GCubeUser + * @param httpServletRequest the {@link HttpServletRequest} object + * @return the current group identifier as long */ public long getCurrentGroupId(HttpServletRequest httpServletRequest) { String groupIdNo = httpServletRequest.getHeader(VRE_ID_ATTR_NAME); @@ -248,13 +277,73 @@ public class PortalContext { } return -1; } - - /** - * @deprecated use only with AJAX Calls - * @param httpServletRequest the httpServletRequest object - * @return the instance of the user - * @see GCubeUser + *

+ * Returns the gCube authorisation token for the given user + *

+ * @param scope infrastrucure context (scope) + * @param userId the GCubeUser user identifier (userId) @see {@link GCubeUser} + * @return the Token for the user in the context, or null if a token for this user could not be found + */ + public String getCurrentUserToken(String scope, long userId) { + if (isWithinPortal()) { + try { + String username = userManager.getUserById(userId).getUsername(); + return getCurrentUserToken(scope, username); + } catch (UserManagementSystemException | UserRetrievalFault e) { + e.printStackTrace(); + } + } + 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; + } + /** + *

+ * Returns the gCube authorisation token for the given user + *

+ * @param scope infrastrucure context (scope) + * @param username the GCubeUser username @see {@link GCubeUser} + * @return the Token for the user in the context, or null if a token for this user could not be found + */ + public String getCurrentUserToken(String scope, String username) { + String userToken = null; + if (isWithinPortal()) { + try { + ScopeProvider.instance.set(scope); + userToken = authorizationService().resolveTokenByUserAndContext(username, scope); + SecurityTokenProvider.instance.set(userToken); + } + catch (ObjectNotFound ex) { + userToken = generateAuthorizationToken(username, scope); + SecurityTokenProvider.instance.set(userToken); + _log.debug("generateAuthorizationToken OK for " + username + " in scope " + scope); + } + catch (Exception e) { + _log.error("Error while trying to generate token for user " + username + "in scope " + scope); + e.printStackTrace(); + return null; + } + } 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 userToken; + } + /** + * @deprecated please use getCurrentUserToken(String scope, String username) or getCurrentUserToken(String scope, long userId) + *

+ * Please note that this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). + *

+ * + * @param httpServletRequest the {@link HttpServletRequest} object + * @return the Token for the user in the context, or null if a token for this user could not be found */ public String getCurrentUserToken(HttpServletRequest httpServletRequest) { String groupIdNo = httpServletRequest.getHeader(VRE_ID_ATTR_NAME); @@ -289,73 +378,6 @@ public class PortalContext { } return userToken; } - /** - * @param httpServletRequest the httpServletRequest object - * @param scope the infrastructure scope - * @return the instance of the user - * @see GCubeUser - */ - public String getCurrentUserToken(String scope, HttpServletRequest httpServletRequest) { - String userToken = null; - if (isWithinPortal()) { - String username = getCurrentUser(httpServletRequest).getUsername(); - try { - ScopeProvider.instance.set(scope); - userToken = authorizationService().resolveTokenByUserAndContext(username, scope); - SecurityTokenProvider.instance.set(userToken); - } - catch (ObjectNotFound ex) { - userToken = generateAuthorizationToken(username, scope); - SecurityTokenProvider.instance.set(userToken); - _log.debug("generateAuthorizationToken OK for " + username + " in scope " + scope); - } - catch (Exception e) { - _log.error("Error while trying to generate token for user " + username + "in scope " + scope); - e.printStackTrace(); - return null; - } - } 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 userToken; - } - /** - * Another way to retrieve the user token - * @param scope the current scope - * @param userId the Liferay's user id - * @return the Token for the user in scope - */ - public String getCurrentUserToken(String scope, long userId) { - String userToken = null; - if (isWithinPortal()) { - String username = null; - try { - ScopeProvider.instance.set(scope); - username = new LiferayUserManager().getUserById(userId).getUsername(); - userToken = authorizationService().resolveTokenByUserAndContext(username, scope); - SecurityTokenProvider.instance.set(userToken); - } - catch (ObjectNotFound ex) { - userToken = generateAuthorizationToken(username, scope); - SecurityTokenProvider.instance.set(userToken); - _log.debug("generateAuthorizationToken OK for " + username + " in scope " + scope); - } - catch (Exception e) { - _log.error("Error while trying to generate token for user " + username + "in scope " + scope); - e.printStackTrace(); - return null; - } - } 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 userToken; - } /** * * @param username @@ -414,7 +436,7 @@ public class PortalContext { } /** * - * @param httpServletRequest + * @param httpServletRequest the {@link HttpServletRequest} object * @return the gateway URL until the first slash, e.g. http(s)://mynode.d4science.org:8080, if the URL uses standard http(s) port like 80 or 443 the port is not returned. */ public String getGatewayURL(HttpServletRequest httpServletRequest) { @@ -458,7 +480,7 @@ public class PortalContext { } /** * - * @param request + * @param httpServletRequest the {@link HttpServletRequest} object * @return the landing page path of the current Site e.g. "/group/i-marine" */ public String getSiteLandingPagePath(final HttpServletRequest request) { @@ -498,7 +520,7 @@ public class PortalContext { } /** * - * @param request + * @param request the {@link HttpServletRequest} object * @return the current Group instance based on the request */ private Group getSiteFromServletRequest(final HttpServletRequest request) throws Exception { @@ -540,11 +562,8 @@ public class PortalContext { return null; } /** - * @param request * @param currentGroup - * @param isPrivate - * @param isUser - * @return + * @return Returns the friendly u r l of this group. */ private static String getGroupFriendlyURL(final Group currentGroup) throws Exception { String friendlyURL = GCubePortalConstants.PREFIX_GROUP_URL; @@ -570,7 +589,7 @@ public class PortalContext { } /** * - * @param request the HttpServletRequest instance of your servlet + * @param httpServletRequest the {@link HttpServletRequest} object * @return the current Site Name based on the request */ public String getGatewayName(HttpServletRequest request) { @@ -613,7 +632,7 @@ public class PortalContext { } /** * - * @param request the HttpServletRequest instance of your servlet + * @param request the {@link HttpServletRequest} object * @return the sender (from) email address for the current Site based on the request */ public String getSenderEmail(HttpServletRequest request) {