Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements administrative methods 
4
 *  Copyright: 2008 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 * 
8
 *   '$Author: leinfelder $'
9
 *     '$Date: 2016-02-09 17:14:56 -0800 (Tue, 09 Feb 2016) $'
10
 * '$Revision: 9520 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat.util;
28

    
29
import java.io.BufferedReader;
30
import java.io.IOException;
31
import java.io.InputStream;
32
import java.io.InputStreamReader;
33
import java.io.PrintWriter;
34
import java.net.MalformedURLException;
35
import java.net.URL;
36
import java.net.URLConnection;
37
import java.util.ArrayList;
38
import java.util.Enumeration;
39
import java.util.HashMap;
40
import java.util.Hashtable;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.Vector;
44

    
45
import javax.servlet.ServletContext;
46
import javax.servlet.ServletException;
47
import javax.servlet.http.Cookie;
48
import javax.servlet.http.HttpServletRequest;
49
import javax.servlet.http.HttpServletResponse;
50
import javax.servlet.http.HttpSession;
51

    
52
import org.apache.commons.io.IOUtils;
53
import org.apache.http.HttpException;
54
import org.apache.http.HttpResponse;
55
import org.apache.http.HttpVersion;
56
import org.apache.http.NameValuePair;
57
import org.apache.http.client.HttpClient;
58
import org.apache.http.client.entity.UrlEncodedFormEntity;
59
import org.apache.http.client.methods.HttpPost;
60
import org.apache.http.message.BasicNameValuePair;
61
import org.apache.http.params.CoreProtocolPNames;
62
import org.apache.log4j.Logger;
63
import org.dataone.portal.PortalCertificateManager;
64
import org.dataone.service.types.v1.Session;
65
import org.dataone.service.types.v1.Subject;
66
import org.dataone.service.types.v1.SubjectInfo;
67

    
68
import edu.ucsb.nceas.metacat.properties.PropertyService;
69
import edu.ucsb.nceas.metacat.service.SessionService;
70
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
71
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
72

    
73
public class RequestUtil {
74
	
75
	private static Logger logMetacat = Logger.getLogger(RequestUtil.class);
76
	private static String encoding = "UTF-8";
77
	
78
	/**
79
	 * private constructor - all methods are static so there is no
80
     * no need to instantiate.
81
	 */
82
	private RequestUtil() {}
83
	
84
	/**
85
	 * Forward a request that was received by this servlet on to another JSP
86
	 * page or servlet to continue handling the request.
87
	 * 
88
	 * @param request
89
	 *            to be forwarded
90
	 * @param response
91
	 *            that can be used for writing output to the client
92
	 * @param destination
93
	 *            the context-relative URL to which the request is forwarded
94
	 * @param params the request parameters.  these will be added to the request
95
	 */
96
	public static void forwardRequest(HttpServletRequest request, HttpServletResponse response, 
97
			String destinationUrl, Hashtable<String, String[]> params) throws MetacatUtilException {
98

    
99
		destinationUrl += "?" + paramsToQuery(params);
100
		
101
		logMetacat.debug("Forwarding request to " + destinationUrl);
102
		ServletContext servletContext = request.getSession()
103
				.getServletContext();
104

    
105
		try {
106
			servletContext.getRequestDispatcher(destinationUrl).forward(request, response);
107
		}  catch (IOException ioe) {
108
			throw new MetacatUtilException("RequestUtil.forwardRequest - I/O error when forwarding to " + 
109
					destinationUrl + " : " + ioe.getMessage());			
110
		} catch (ServletException se) {
111
			throw new MetacatUtilException("RequestUtil.forwardRequest - Servlet error when forwarding to " + 
112
					destinationUrl + " : " + se.getMessage());			
113
		}
114
	}
115
	
116
	/**
117
	 * Forward a request that was received by this servlet on to another JSP
118
	 * page or servlet to continue handling the request.  In this case, the page
119
	 * must be referenced in a paramter named "forwardto".  If the qformat is 
120
	 * provided, the file will be retrieved from that skin.  Otherwise, the file 
121
	 * will be retrieved from the system default skin.
122
	 * 
123
	 * For more specific file location, use: forwardRequest(request,response, destinationUrl, params)
124
	 * 
125
	 * @param request
126
	 *            to be forwarded
127
	 * @param response
128
	 *            that can be used for writing output to the client
129
	 * @param params
130
	 *            the request parameters.  these will be added to the request.
131
	 */
132
	public static void forwardRequest(HttpServletRequest request, HttpServletResponse response, 
133
			Hashtable<String, String[]> params) throws MetacatUtilException {
134

    
135
		String forwardTos[] = params.get("forwardto");
136
		if (forwardTos == null || forwardTos[0].equals("")) {
137
			throw new MetacatUtilException("RequestUtil.forwardRequest - forwardto must be set in parameters when forwarding.");			
138
		}
139
		
140
		String forwardTo = forwardTos[0];
141
		String qformat = null;
142
		
143
		String qformats[] = params.get("qformat");
144
		if (qformats == null || qformats.length == 0) {
145
			try {
146
				qformat = PropertyService.getProperty("application.default-style");
147
			} catch (PropertyNotFoundException pnfe) {
148
				qformat = "default";
149
				logMetacat.warn("RequestUtil.forwardRequest - could not get property " + 
150
						"'application.default-style'. Using 'default'");
151
			}
152
		} else {
153
			qformat = qformats[0];
154
		}
155
		
156
		String destinationUrl = "/style/skins/" + qformat + "/" + forwardTo;
157
		destinationUrl += "?" + paramsToQuery(params);
158
		
159
		logMetacat.debug("RequestUtil.forwardRequest - Forwarding request to " + destinationUrl);
160
		ServletContext servletContext = request.getSession()
161
				.getServletContext();
162
		try {
163
			servletContext.getRequestDispatcher(destinationUrl).forward(request, response);
164
		} catch (IOException ioe) {
165
			throw new MetacatUtilException("RequestUtil.forwardRequest - I/O error when forwarding to " + 
166
					destinationUrl + " : " + ioe.getMessage());			
167
		} catch (ServletException se) {
168
			throw new MetacatUtilException("RequestUtil.forwardRequest - Servlet error when forwarding to " + 
169
					destinationUrl + " : " + se.getMessage());			
170
		}
171
	}
172
	
173

    
174

    
175
	/**
176
	 * Post a request and return the response body
177
	 * 
178
	 * @param httpClient
179
	 *            The HttpClient to use in the post.  This is passed in because
180
     * 			  the same client may be used in several posts
181
	 * @param url
182
	 *            the url to post to
183
	 * @param paramMap
184
	 *            map of parameters to add to the post
185
	 * @returns a string holding the response body
186
	 */
187
	public static String post(HttpClient httpclient, String url,
188
			HashMap<String, String> paramMap) throws IOException, HttpException {
189

    
190
        httpclient.getParams().setParameter(
191
        		CoreProtocolPNames.PROTOCOL_VERSION, 
192
        	    HttpVersion.HTTP_1_1);
193
    	httpclient.getParams().setParameter(
194
    			CoreProtocolPNames.HTTP_CONTENT_CHARSET, 
195
    			encoding );
196
        HttpPost post = new HttpPost(url);
197
        //set the params
198
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
199
        Iterator<String> keys = paramMap.keySet().iterator();
200
        while (keys.hasNext()) {
201
        	String key = keys.next();
202
        	String value = paramMap.get(key);
203
        	NameValuePair nvp = new BasicNameValuePair(key, value);
204
        	nameValuePairs.add(nvp);
205
        }
206
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs, encoding));
207
        //post.setHeader("Cookie", "JSESSIONID="+ sessionId);
208
        HttpResponse httpResponse = httpclient.execute(post);
209
        if (httpResponse.getStatusLine().getStatusCode() != -1) {
210
            InputStream result = httpResponse.getEntity().getContent();
211
            String contents = IOUtils.toString(result, encoding);
212
            return contents;
213
        }
214
        
215
		return null;
216
	}
217
	
218
	public static String get(String urlString, Hashtable<String, String[]> params)  throws MetacatUtilException {	
219
		try {
220
			URL url = new URL(urlString);
221
			URLConnection urlConn = url.openConnection();
222
			
223
			urlConn.setDoOutput(true);
224
			
225
			PrintWriter pw = new PrintWriter(urlConn.getOutputStream());
226
			String queryString = paramsToQuery(params);
227
			logMetacat.debug("Sending get request: " + urlString + "?" + queryString);
228
			pw.print(queryString);
229
			pw.close();
230
			
231
			// get the input from the request
232
			BufferedReader in = 
233
				new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
234
			
235
			StringBuffer sb = new StringBuffer();
236
			String line;
237
			while ((line = in.readLine()) != null) {
238
				sb.append(line);
239
			}
240
			in.close();
241
			
242
			return sb.toString();
243
		} catch (MalformedURLException mue) {
244
			throw new MetacatUtilException("URL error when contacting: " + urlString + " : " + mue.getMessage());
245
		} catch (IOException ioe) {
246
			throw new MetacatUtilException("I/O error when contacting: " + urlString + " : " + ioe.getMessage());
247
		} 
248
	}
249
	
250
	/**
251
	 * Get a cookie from a request by the cookie name
252
	 * 
253
	 * @param request
254
	 *            the request from which to get the cookie
255
	 * @param cookieName
256
	 *            the name of the cookie to look for
257
	 */
258
	public static Cookie getCookie(HttpServletRequest request, String cookieName)  {
259
		Cookie sessionCookies[] = request.getCookies();
260

    
261
		if (sessionCookies == null) {
262
			return null;
263
		}
264
		
265
		for (int i = 0; i < sessionCookies.length; i++) {
266
			if(sessionCookies[i].getName().equals(cookieName)) {
267
				return sessionCookies[i];
268
			}
269
		}	
270
		
271
		return null;
272
	}
273
	
274
	/**
275
	 * Get the session data from a request. The Scenarios we can run across
276
	 * here: 
277
	 * -- the session id parameter was set in the request parameters 
278
	 * -- request.getSession returns a new session. There is a chance that the
279
	 *    session id was set in a cookie. Check for a JSESSIONID cookie and use
280
	 *    that id if provided. 
281
	 * -- request.getSession returns a session that is a)
282
	 *    preexisting or b) new but without a JSESSIONID cookie. Use the session id
283
	 *    from this session
284
	 * 
285
	 * @param request
286
	 *            the request from which to get the session data
287
	 * @return the session data object representing the active session for this
288
	 *         request. If there is no active session, the public session data
289
	 *         is returned
290
	 */
291
	public static SessionData getSessionData(HttpServletRequest request) {
292
		SessionData sessionData = null;
293
		String sessionId = null;
294
		
295
		// check for auth token first
296
		sessionData = getSessionDataFromToken(request);
297
		if (sessionData != null) {
298
			return sessionData;
299
		}
300

    
301
		Hashtable<String, String[]> params = getParameters(request);
302

    
303
		if (params.containsKey("sessionid")) {
304
			// the session id is specified in the request parameters
305
			sessionId = ((String[]) params.get("sessionid"))[0];
306
			logMetacat.debug("session ID provided in request properties: " + sessionId);
307
		} else {
308
			HttpSession session = request.getSession(true);
309
			if (session.isNew()) {
310
				// this is a new session
311
				Cookie sessionCookie = RequestUtil.getCookie(request, "JSESSIONID");
312
				if (sessionCookie != null) {
313
					// and there is a JSESSIONID cookie
314
					sessionId = sessionCookie.getValue();
315
					logMetacat.debug("session ID provided in request cookie: "
316
							+ sessionId);
317
				}
318
			}
319
			if (sessionId == null) {
320
				// there is an existing session (session is old)
321
				sessionId = session.getId();
322
				logMetacat.debug("session ID retrieved from request: " + sessionId);
323
			}
324
		}
325

    
326
		// if the session id is registered in SessionService, get the
327
		// SessionData for it. Otherwise, use the public session.
328
		if (SessionService.getInstance().isSessionRegistered(sessionId)) {
329
			logMetacat.debug("retrieving session data from session service "
330
					+ "for session id " + sessionId);
331
			sessionData = SessionService.getInstance().getRegisteredSession(sessionId);
332
		} else {
333
			logMetacat.debug("using public session.  Given session id is "
334
					+ "registered: " + sessionId);
335
			sessionData = SessionService.getInstance().getPublicSession();
336
		}
337
		
338
		return sessionData;
339
	}
340
	
341
	/**
342
	 * Get SessionData from the DataONE auth token
343
	 * @param request
344
	 * @return
345
	 */
346
	public static SessionData getSessionDataFromToken(HttpServletRequest request) {
347
		SessionData sessionData = null;
348
		
349
    	Session session = PortalCertificateManager.getInstance().getSession(request);
350
    	if (session != null) {
351
    		SubjectInfo subjectInfo = session.getSubjectInfo();
352
			String userName = session.getSubject().getValue();
353
			String id = request.getSession().getId();
354
			String password = null;
355
    		String[] groupNames = null;
356
			String name = null;
357
			if (subjectInfo != null && subjectInfo.getPersonList() != null && subjectInfo.getPersonList().size() > 0) {
358
				name = subjectInfo.getPerson(0).getFamilyName();
359
				if (subjectInfo.getPerson(0).getGivenNameList() != null && subjectInfo.getPerson(0).getGivenNameList().size() > 0) {
360
					name = subjectInfo.getPerson(0).getGivenName(0) + " " + name;
361
				}
362
				List<String> groups = new ArrayList<String>();
363
				if (subjectInfo.getPerson(0).getIsMemberOfList() != null) {
364
					for (Subject group: subjectInfo.getPerson(0).getIsMemberOfList()) {
365
						groups.add(group.getValue());
366
					}
367
					groupNames = groups.toArray(new String[0]);
368
				}
369
			}
370
			
371
			// construct the session
372
			sessionData = new SessionData(id , userName, groupNames, password, name);
373
			
374
			//TODO: register this session for later or do this each time?
375
			//SessionService.getInstance().registerSession(sessionData);
376
			
377
    		
378
    	}
379
		
380
		return sessionData;
381
	}
382

    
383
	/**
384
	 * Get a cookie from a request by the cookie name
385
	 * 
386
	 * @param request
387
	 *            the request from which to get the cookie
388
	 * @param cookieName
389
	 *            the name of the cookie to look for
390
	 */
391
	@SuppressWarnings("unchecked")
392
	public static Hashtable<String, String[]> getParameters(HttpServletRequest request)  {
393
		Hashtable<String, String[]> params = new Hashtable<String, String[]>();
394
		
395
		Enumeration<String> paramlist = (Enumeration<String>)request.getParameterNames();
396
		while (paramlist.hasMoreElements()) {
397
			String name = (String) paramlist.nextElement();
398
			String[] value = request.getParameterValues(name);
399
			params.put(name, value);
400
		}
401
		
402
		return params;
403
	}
404
	
405
	/**
406
	 * Add a list of errors to the request. The pages will pick up the errors
407
	 * and display them where appropriate.
408
	 * 
409
	 * @param request
410
	 *            the request that will get forwarded
411
	 * @param errorVector
412
	 *            a list of error strings
413
	 */
414
	public static void setRequestErrors(HttpServletRequest request,
415
			Vector<String> errorVector) {
416
		request.setAttribute("formErrors", "true");
417
		request.setAttribute("processingErrors", errorVector);
418
	}
419
	
420
	/**
421
	 * Add a list of form errors to the request. The pages will pick up the
422
	 * errors and display them where appropriate.
423
	 * 
424
	 * @param request
425
	 *            the request that will get forwarded
426
	 * @param errorVector
427
	 *            a list of form error strings
428
	 */
429
	public static void setRequestFormErrors(HttpServletRequest request,
430
			Vector<String> errorVector) {
431
		request.setAttribute("formErrors", "true");
432
		request.setAttribute("formFieldErrors", errorVector);
433
	}
434
	
435
	/**
436
	 * Add a list of success messages to the request. The pages will pick up the
437
	 * messages and display them where appropriate.
438
	 * 
439
	 * @param request
440
	 *            the request that will get forwarded
441
	 * @param errorVector
442
	 *            a list of success message strings
443
	 */
444
	public static void setRequestSuccess(HttpServletRequest request,
445
			Vector<String> successVector) {
446
		request.setAttribute("formSuccess", "true");
447
		request.setAttribute("processingSuccess", successVector);
448
	}
449
	
450
	/**
451
	 * Add a list of general messages to the request. The pages will pick up the
452
	 * messages and display them where appropriate.
453
	 * 
454
	 * @param request
455
	 *            the request that will get forwarded
456
	 * @param errorVector
457
	 *            a list of general message strings
458
	 */
459
	public static void setRequestMessage(HttpServletRequest request,
460
			Vector<String> messageVector) {
461
		request.setAttribute("formMessage", "true");
462
		request.setAttribute("processingMessage", messageVector);
463
	}
464
	
465
	/**
466
	 * Add a list of general messages to the request. The pages will pick up the
467
	 * messages and display them where appropriate.
468
	 * 
469
	 * @param request
470
	 *            the request that will get forwarded
471
	 * @param errorVector
472
	 *            a list of general message strings
473
	 */
474
	public static void clearRequestMessages(HttpServletRequest request) {
475
		request.setAttribute("formMessage", null);
476
		request.setAttribute("formSuccess", null);
477
		request.setAttribute("formErrors", null);
478
		request.setAttribute("processingMessage", null);
479
		request.setAttribute("processingSuccess", null);
480
		request.setAttribute("formFieldErrors", null);
481
		request.setAttribute("processingErrors", null);
482
	}
483
	
484
	/**
485
	 * Add the user's login id to the session on this request
486
	 * 
487
	 * @param request
488
	 *            the request that will get forwarded
489
	 * @param userId
490
	 *            the user's login id
491
	 */
492
	public static void setUserId(HttpServletRequest request, String userId) {
493
		request.getSession().setAttribute("userId", userId);
494
	}
495
	
496
	private static String paramsToQuery(Hashtable<String, String[]> params) {
497
		String query = "";
498
		if (params != null) {
499
			boolean firstParam = true;
500
			for (String paramName : params.keySet()) {
501
				if (firstParam) {
502
					firstParam = false;
503
				} else {
504
					query += "&";
505
				}
506
				query += paramName + "=" + params.get(paramName)[0];
507
			}
508
		}
509
		
510
		return query;
511
	}
512
	
513

    
514
}
(14-14/18)