From ddf84b1bc0f3b7e3c369c5000d6fd936003ddadc Mon Sep 17 00:00:00 2001
From: gmantele <gmantele@ari.uni-heidelberg.de>
Date: Tue, 17 Feb 2015 11:10:46 +0100
Subject: [PATCH] [UWS,TAP] Set the user who submits the request in an
 HttpServletRequest attribute. Thus, every TAP and UWS resources can get it
 without extracting the information every time from the HttpServletRequest.

---
 src/tap/resource/TAP.java       | 23 +++++++++---------
 src/uws/UWSToolBox.java         | 43 +++++++++++++++++++++++++++++++--
 src/uws/service/UWS.java        |  8 ++++--
 src/uws/service/UWSService.java |  6 ++---
 src/uws/service/UWSServlet.java |  6 ++---
 5 files changed, 64 insertions(+), 22 deletions(-)

diff --git a/src/tap/resource/TAP.java b/src/tap/resource/TAP.java
index 15e789b..b30fbb7 100644
--- a/src/tap/resource/TAP.java
+++ b/src/tap/resource/TAP.java
@@ -16,7 +16,7 @@ package tap.resource;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -45,11 +45,11 @@ import tap.log.TAPLog;
 import tap.metadata.TAPMetadata;
 import uk.ac.starlink.votable.VOSerializer;
 import uws.UWSException;
+import uws.UWSToolBox;
 import uws.job.ErrorType;
 import uws.job.user.JobOwner;
 import uws.service.UWS;
 import uws.service.UWSService;
-import uws.service.UWSUrl;
 import uws.service.error.ServiceErrorWriter;
 import uws.service.log.UWSLog.LogLevel;
 import adql.db.FunctionDef;
@@ -60,7 +60,7 @@ import adql.db.FunctionDef;
  * <p>At its creation it is creating and configuring the other resources in function of the given description of the TAP service.</p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.0 (01/2015)
+ * @version 2.0 (02/2015)
  */
 public class TAP implements VOSIResource {
 
@@ -710,19 +710,18 @@ public class TAP implements VOSIResource {
 			getLogger().logUWS(LogLevel.INFO, this, "INIT", "TAP successfully initialized.", null);
 		}
 
-		JobOwner owner = null;
+		JobOwner user = null;
 		try{
 			// Identify the user:
 			try{
-				if (service.getUserIdentifier() != null)
-					owner = service.getUserIdentifier().extractUserId(new UWSUrl(request), request);
+				user = UWSToolBox.getUser(request, service.getUserIdentifier());
 			}catch(UWSException ue){
 				throw new TAPException(ue);
 			}
 
 			// Display the TAP Main Page:
 			if (resourceName.equals("homePage"))
-				writeHomePage(response, owner);
+				writeHomePage(response, user);
 			// or Display/Execute the selected TAP Resource:
 			else{
 				// search for the corresponding resource:
@@ -739,22 +738,22 @@ public class TAP implements VOSIResource {
 
 			// Log the successful execution of the action, only if the asked resource is not UWS (because UWS is already logging the received request):
 			if (!resourceName.equalsIgnoreCase(ASync.RESOURCE_NAME))
-				getLogger().logHttp(LogLevel.INFO, response, reqID, owner, "HTTP " + UWSException.OK + " - Action \"" + resourceName + "\" successfully executed.", null);
+				getLogger().logHttp(LogLevel.INFO, response, reqID, user, "HTTP " + UWSException.OK + " - Action \"" + resourceName + "\" successfully executed.", null);
 
 		}catch(Throwable t){
 			// CLIENT ABORTION: (note: should work with Apache/Tomcat and JBoss)
 			if (t.getClass().getName().endsWith("ClientAbortException")){
 				// Log the client abortion:
-				getLogger().logHttp(LogLevel.INFO, response, reqID, owner, "HTTP " + response.getStatus() + " - HTTP request aborted by the client => the TAP resource \"" + resourceName + "\" has stopped!", t);
+				getLogger().logHttp(LogLevel.INFO, response, reqID, user, "HTTP " + response.getStatus() + " - HTTP request aborted by the client => the TAP resource \"" + resourceName + "\" has stopped!", t);
 				// Notify the client abortion in a TAP error:
-				errorWriter.writeError("The client aborts this HTTP request! It may happen due to a client timeout or to an interruption of the response waiting process.", ErrorType.TRANSIENT, UWSException.ACCEPTED_BUT_NOT_COMPLETE, response, request, reqID, owner, resourceName);
+				errorWriter.writeError("The client aborts this HTTP request! It may happen due to a client timeout or to an interruption of the response waiting process.", ErrorType.TRANSIENT, UWSException.ACCEPTED_BUT_NOT_COMPLETE, response, request, reqID, user, resourceName);
 			}
 			// ANY OTHER ERROR:
 			else{
 				// Write the error in the response and return the appropriate HTTP status code:
-				errorWriter.writeError(t, response, request, reqID, owner, resourceName);
+				errorWriter.writeError(t, response, request, reqID, user, resourceName);
 				// Log the error:
-				getLogger().logHttp(LogLevel.ERROR, response, reqID, owner, "HTTP " + response.getStatus() + " - Can not complete the execution of the TAP resource \"" + resourceName + "\"!", t);
+				getLogger().logHttp(LogLevel.ERROR, response, reqID, user, "HTTP " + response.getStatus() + " - Can not complete the execution of the TAP resource \"" + resourceName + "\"!", t);
 			}
 		}finally{
 			// Notify the queue of the asynchronous jobs that a new connection may be available:
diff --git a/src/uws/UWSToolBox.java b/src/uws/UWSToolBox.java
index 9e48842..de7e3f3 100644
--- a/src/uws/UWSToolBox.java
+++ b/src/uws/UWSToolBox.java
@@ -16,7 +16,7 @@ package uws;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -41,8 +41,10 @@ import javax.servlet.http.HttpServletResponse;
 
 import uws.job.ErrorSummary;
 import uws.job.UWSJob;
+import uws.job.user.JobOwner;
 import uws.service.UWS;
 import uws.service.UWSUrl;
+import uws.service.UserIdentifier;
 import uws.service.log.DefaultUWSLog;
 import uws.service.log.UWSLog;
 import uws.service.request.RequestParser;
@@ -52,7 +54,7 @@ import uws.service.request.UploadFile;
  * Some useful functions for the managing of a UWS service.
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (12/2014)
+ * @version 4.1 (02/2015)
  */
 public class UWSToolBox {
 
@@ -394,6 +396,43 @@ public class UWSToolBox {
 		return cnt;
 	}
 
+	/* *************** */
+	/* USER EXTRACTION */
+	/* *************** */
+	/**
+	 * <p>Extract the user/job owner from the given HTTP request.</p>
+	 * 
+	 * Two cases are supported:
+	 * <ol>
+	 * 	<li><b>The user has already been identified and is stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER}</b> => the stored value is returned.</li>
+	 * 	<li><b>No HTTP attribute and a {@link UserIdentifier} is provided</b> => the user is identified with the given {@link UserIdentifier} and stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} before being returned.</li>
+	 * </ol>
+	 * 
+	 * <p>In any other case, NULL is returned.</p>
+	 * 
+	 * @param request			The HTTP request from which the user must be extracted. <i>note: if NULL, NULL will be returned.</i>
+	 * @param userIdentifier	The method to use in order to extract a user from the given request. <i>note: if NULL, NULL is returned IF no HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} can be found.</i>
+	 * 
+	 * @return	The identified user. <i>MAY be NULL</i>
+	 * 
+	 * @throws NullPointerException	If an error occurs while extracting a {@link UWSUrl} from the given {@link HttpServletRequest}.
+	 * @throws UWSException			If any error occurs while extracting a user from the given {@link HttpServletRequest}.
+	 * 
+	 * @since 4.1
+	 */
+	public static final JobOwner getUser(final HttpServletRequest request, final UserIdentifier userIdentifier) throws NullPointerException, UWSException{
+		if (request == null)
+			return null;
+		else if (request.getAttribute(UWS.REQ_ATTRIBUTE_USER) != null)
+			return (JobOwner)request.getAttribute(UWS.REQ_ATTRIBUTE_USER);
+		else if (userIdentifier != null){
+			JobOwner user = userIdentifier.extractUserId(new UWSUrl(request), request);
+			request.setAttribute(UWS.REQ_ATTRIBUTE_USER, user);
+			return user;
+		}else
+			return null;
+	}
+
 	/* **************************** */
 	/* DIRECTORY MANAGEMENT METHODS */
 	/* **************************** */
diff --git a/src/uws/service/UWS.java b/src/uws/service/UWS.java
index 9c545b2..4820444 100644
--- a/src/uws/service/UWS.java
+++ b/src/uws/service/UWS.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -64,7 +64,7 @@ import uws.service.request.UWSRequestParser;
  * </b></p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (12/2014)
+ * @version 4.1 (02/2015)
  */
 public interface UWS extends Iterable<JobList> {
 
@@ -76,6 +76,10 @@ public interface UWS extends Iterable<JobList> {
 	 * @since 4.1 */
 	public static final String REQ_ATTRIBUTE_PARAMETERS = "UWS_PARAMETERS";
 
+	/** Attribute of the HttpServletRequest to set and to get in order to access the user at the origin of the HTTP request.
+	 * @since 4.1 */
+	public static final String REQ_ATTRIBUTE_USER = "UWS_USER";
+
 	/**
 	 * Gets the name of this UWS.
 	 * 
diff --git a/src/uws/service/UWSService.java b/src/uws/service/UWSService.java
index 4b93575..4c16c49 100644
--- a/src/uws/service/UWSService.java
+++ b/src/uws/service/UWSService.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -186,7 +186,7 @@ import uws.service.request.RequestParser;
  * 
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (01/2015)
+ * @version 4.1 (02/2015)
  */
 public class UWSService implements UWS {
 
@@ -1127,7 +1127,7 @@ public class UWSService implements UWS {
 			urlInterpreter.load(request);
 
 			// Identify the user:
-			user = (userIdentifier == null) ? null : userIdentifier.extractUserId(urlInterpreter, request);
+			user = UWSToolBox.getUser(request, userIdentifier);
 
 			// Apply the appropriate UWS action:
 			for(int i = 0; action == null && i < uwsActions.size(); i++){
diff --git a/src/uws/service/UWSServlet.java b/src/uws/service/UWSServlet.java
index b85ebc5..17c7481 100644
--- a/src/uws/service/UWSServlet.java
+++ b/src/uws/service/UWSServlet.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -132,7 +132,7 @@ import uws.service.request.UploadFile;
  * </p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (01/2015)
+ * @version 4.1 (02/2015)
  */
 public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory {
 	private static final long serialVersionUID = 1L;
@@ -341,7 +341,7 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
 			requestUrl.load(req);
 
 			// Identify the user:
-			user = (userIdentifier == null) ? null : userIdentifier.extractUserId(requestUrl, req);
+			user = UWSToolBox.getUser(req, userIdentifier);
 
 			// METHOD GET:
 			if (method.equals("GET")){
-- 
GitLab