Difference between revisions of "Portal Context"

From Gcube Wiki
Jump to: navigation, search
(Getting the current user in custom servlet)
(Getting the current user in custom servlet)
Line 190: Line 190:
 
         ...
 
         ...
 
         PortalContext pContext = PortalContext.getConfiguration();
 
         PortalContext pContext = PortalContext.getConfiguration();
         String username = getCurrentUserPortalDelegateServlet(httpServletRequest).getUsername();
+
         GCubeUser theUser = getCurrentUserPortalDelegateServlet(httpServletRequest);
 
         ...
 
         ...
 
</source>
 
</source>

Revision as of 11:54, 12 January 2017

Introduction

Overview

What is a portal context?

It is the component you must use to (programmatically) get:

  • the current user identifier using your webapp/portlet;
  • the current scope (infrastructure context) the user is currently working;
  • the user (authorisation) token for that scope (infrastructure context).

Apart from that, portal context provides your application with contextual information about the gCube Gateway your webapp/portlet is running on, for instance you can:

  • retrieve the list of Virtual Organizations available on a given portal;
  • retrieve the configured senders of emails sent by the portal;
  • retrieve the gateway name.

Additionally, you can exploit the Centralised Email Manager when needing to send Emails from any application/portlet running on a gCube Gateway.

Maven Dependency

In order to use it in your project, add the following dependency to the project's pom.xml file

<dependency>
	<groupId>org.gcube.common.portal</groupId>
	<artifactId>portal-manager</artifactId>
	<scope>provided</scope>
</dependency>

PortalContext Usage/Examples

First, get an instance of the PortalContext by invoking the static method PortalContext.getConfiguration();

PortalContext instance = PortalContext.getConfiguration();

Getting the current User

Please note: this method works with AJAX calls only (i.e. XMLHttpRequest to exchange data with a server behind the scenes). To let a custom servlet run in the context of the ROOT application and therefore allowing, for example, the access to the same session you must use the PortalDelegateServlet feature.

  • Get the current username of the current user:
import org.gcube.common.portal;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
...
PortalContext pContext = PortalContext.getConfiguration();
String username = pContext.getCurrentUser(httpServletRequest).getUsername();
  • Get the user object (GCubeUser, see [2] bottom of this page) of the current user:
import org.gcube.common.portal;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
...
PortalContext pContext = PortalContext.getConfiguration();
GCubeUser theUser = pContext.getCurrentUser(httpServletRequest);

Getting the infrastructure Context (Scope)

Please note: the following methods needed to get the infrastructure context work with AJAX calls (i.e. XMLHttpRequest to exchange data with a server behind the scenes) only. If you use standard http GET or POST to exchange data with a server, you must handle the infrastructure context information differently. Please see the following page for further information read ClientContextLibrary [3] bottom of this page.

  • Get the current scope (a.k.a. the infrastructure context):
import org.gcube.common.portal;
...
PortalContext pContext = PortalContext.getConfiguration();
String currentScope = pContext.getCurrentScope(httpServletRequest);
  • Get the current user token:
import org.gcube.common.portal;
...
PortalContext pContext = PortalContext.getConfiguration();
String userToken = pContext.getCurrentUserToken(httpServletRequest);
  • Get the current group id (we map VREs with Liferay groups, the groupid identifies the VRE univocally in Liferay).
import org.gcube.common.portal;
...
PortalContext pContext = PortalContext.getConfiguration();
long currGroupId = pContext.getCurrentGroupId(httpServletRequest);

Getting the current Infrastructure name

  • the name of the current infrastructure in which the application is running on:
package org.gcube.common.portal;
....
// get the current infrastructure name
String infrastructureName = instance.getInfrastructureName();
  • retrieve the list of VOs
// get the VOs
List<String> listVo = instance.getVOs();

Getting the Gateway (Server) information

  • Get name of the gateway and its URL:
package org.gcube.common.portal;
...
// get the gateway name given the HttpServletRequest
String gatewayName = instance.getGatewayName(request);
 
// get the gateway url given the HttpServletRequest
String gatewayUrl = instance.getGatewayUrl(request);
  • Get landing page path of the current VRE or VO e.g. "/group/i-marine"
package org.gcube.common.portal;
...
// get the landing page path of the current Site e.g. "/group/i-marine"
String landingPagePath = instance.getSiteLandingPagePath(request);

Liferay's PortalDelegateServlet (Custom servlets running in the ROOT context)

Liferay offers the possibility to run a custom servlet in its context (the ROOT context). Whenever your custom servlet needs to access the Liferay's session (e.g. get the current user) this is the only reliable option to use.

PortalDelegateServlet purpose is to delegate matching requests to another servlet that is running in another context. In that servlet, getSession can be used to retrieve the session that is used by Liferay as well.

It is pretty easy to do so, only the web.xml of your custom servlet has to be modified.

Suppose that you have one custom servlet named org.gcube.portal.example.ExampleServlet. As you can see in the web.xml snippet below, two parameters are used to configure the delegation servlet:

  • the first one defines the servlet class to which requests are delegated;
  • the second parameter defines the sub context path for the delegation. This second parameter is optional, when missing, the servlet name is used.
In the given web.xml example, all requests to "/delegate/an-example-name" are delegated to the configured org.gcube.portal.example.ExampleServlet
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<servlet>
		<servlet-name>an-example-name</servlet-name>
		<servlet-class>com.liferay.portal.kernel.servlet.PortalDelegateServlet</servlet-class>
		<init-param>
			<param-name>servlet-class</param-name>
			<param-value>org.gcube.portal.example.ExampleServlet</param-value>
		</init-param>
		<init-param>
			<param-name>sub-context</param-name>
			<param-value>an-example-name</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
</web-app>

Getting the current user in custom servlet

Now you can get the current logged in user by means of Liferay's PortalUtil (com.liferay.portal.util.PortalUtil) class. See the snippet below:

import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import com.liferay.portal.util.PortalUtil;
...
...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
        ...
        PortalContext pContext = PortalContext.getConfiguration();
        GCubeUser theUser = getCurrentUserPortalDelegateServlet(httpServletRequest);
        ...

Recommendations on servlet sub context names

Please note: your custom servlet context will no longer be the original, it will be "/delegate" and the sub context the one you indicate in the web.xml (e.g. http://next.d4science.org/delegate/an-example-name). Therefore you are strongly recommended to not use general sub context names (such as Download-Servlet).

Please use application specific names to distinguish them from the other delegated sub contexts that may be present (e.g. always prepend $appname- to your sub-context e.g workspace-download-servlet, accounting-csv-download etc.). If you are not sure please email us.

You can also SVN check-out a working (delegated) custom servlet example from here: [1] or see the web-xml here [2]

Centralised Email Manager

The constructor expects the following parameters:

public EmailNotification(String recipient, String subject, String body, HttpServletRequest httpServletRequest)

once the object is instantiated just use the public void sendEmail() method to add the email to queue. The email will be delivered within minutes.

How to use it:

package org.gcube.common.portal.mailing;
 
//instanciate
EmailNotification mailToSend = new EmailNotification(
					email , 
					subject, 
					emailText, 
					request);
//send
mailToSend sendEmail();

Please note that you can also cc and bcc people.

Getting the Portal Context in your IDE (Development)

The client context relies on Liferay.ThemeDisplay javascript object, which obviously is not available if you run your application outside the gCube portal. To overcome this limitation and allow developers to test their applications in any IDE (e.g. Eclipse), you can configure a property file on your development machine containing the context information you need for development purposes.

The name of the file must be gcube-dev-context.properties, and must be placed under an environment variable defined in the run configuration on your IDE called GCUBE_DEV_HOME. The PortalManager will recognize if the application is running on an actual gateway or on an IDE and, in the latter case, retrieves and uses the information written in this file for your application.

# ONLY FOR LOCAL (IDE) DEVELOPMENT - NOT FOR PRODUCTION USE!
# Place this file under $GCUBE_DEV_HOME/ note that the environment variable GCUBE_DEV_HOME must be set on your IDE
# change the properties with your user data and desired scope / token
 
# a development user 
user.username=test.user
user.name=aTestName
user.lastname=aTestLastName
user.email=testing.user@gcube-system.org
 
# a development scope (the scope must be bound to the token below)
development.context=/gcube/devsec/devVRE
development.groupname=devVRE
development.groupid=-1
 
# a valid user token on the (above) development scope.
# you can obtain it by registering on one development VRE and using Token Generator portlet
user.token= ....


Example of GCUBE_DEV_HOME environment variable in a web application Running Configuration on the Eclipse IDE

GCUBE DEV HOME.png

Related links and references

[1] Liferay Javascript Object usage: https://web.liferay.com/web/pankaj.kathiriya/blog/-/blogs/usage-of-liferay-js-object

[2] gCube UsersManagement Library https://wiki.gcube-system.org/gcube/UserManagement_Core#UserManager_APIs

[3] gCube ClientContext Library https://wiki.gcube-system.org/gcube/ClientContextLibrary