[3309] | 1 | package org.greenstone.gsdl3;
|
---|
| 2 |
|
---|
[27617] | 3 | import java.io.File;
|
---|
| 4 | import java.io.FileInputStream;
|
---|
| 5 | import java.io.FileOutputStream;
|
---|
[25717] | 6 | import java.io.IOException;
|
---|
| 7 | import java.io.PrintWriter;
|
---|
| 8 | import java.io.Serializable;
|
---|
| 9 | import java.lang.reflect.Type;
|
---|
[27617] | 10 | import java.nio.channels.FileChannel;
|
---|
[25717] | 11 | import java.util.ArrayList;
|
---|
[27617] | 12 | import java.util.Collection;
|
---|
[25717] | 13 | import java.util.Enumeration;
|
---|
| 14 | import java.util.HashMap;
|
---|
| 15 | import java.util.Hashtable;
|
---|
| 16 | import java.util.Iterator;
|
---|
| 17 | import java.util.List;
|
---|
| 18 | import java.util.Map;
|
---|
| 19 |
|
---|
| 20 | import javax.servlet.ServletConfig;
|
---|
| 21 | import javax.servlet.ServletException;
|
---|
| 22 | import javax.servlet.http.Cookie;
|
---|
| 23 | import javax.servlet.http.HttpServletRequest;
|
---|
| 24 | import javax.servlet.http.HttpServletResponse;
|
---|
| 25 | import javax.servlet.http.HttpSession;
|
---|
| 26 | import javax.servlet.http.HttpSessionBindingEvent;
|
---|
| 27 | import javax.servlet.http.HttpSessionBindingListener;
|
---|
[27617] | 28 | import javax.servlet.http.Part;
|
---|
[25717] | 29 |
|
---|
[27617] | 30 | import org.apache.commons.fileupload.FileItem;
|
---|
| 31 | import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
---|
| 32 | import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
---|
[25717] | 33 | import org.apache.commons.lang3.StringUtils;
|
---|
| 34 | import org.apache.log4j.Logger;
|
---|
| 35 | import org.greenstone.gsdl3.action.PageAction;
|
---|
| 36 | import org.greenstone.gsdl3.comms.Communicator;
|
---|
| 37 | import org.greenstone.gsdl3.comms.SOAPCommunicator;
|
---|
| 38 | import org.greenstone.gsdl3.core.DefaultReceptionist;
|
---|
| 39 | import org.greenstone.gsdl3.core.MessageRouter;
|
---|
| 40 | import org.greenstone.gsdl3.core.Receptionist;
|
---|
[25257] | 41 | import org.greenstone.gsdl3.service.Authentication;
|
---|
[25717] | 42 | import org.greenstone.gsdl3.util.GSConstants;
|
---|
| 43 | import org.greenstone.gsdl3.util.GSParams;
|
---|
| 44 | import org.greenstone.gsdl3.util.GSXML;
|
---|
| 45 | import org.greenstone.gsdl3.util.UserContext;
|
---|
| 46 | import org.greenstone.gsdl3.util.XMLConverter;
|
---|
[27617] | 47 | import org.greenstone.util.GlobalProperties;
|
---|
[27073] | 48 | import org.json.JSONObject;
|
---|
[3652] | 49 | import org.w3c.dom.Document;
|
---|
| 50 | import org.w3c.dom.Element;
|
---|
[16374] | 51 | import org.w3c.dom.Node;
|
---|
[4259] | 52 | import org.w3c.dom.NodeList;
|
---|
[25635] | 53 |
|
---|
[24052] | 54 | import com.google.gson.Gson;
|
---|
| 55 | import com.google.gson.reflect.TypeToken;
|
---|
| 56 |
|
---|
[24753] | 57 | /**
|
---|
| 58 | * a servlet to serve the greenstone library - we are using servlets instead of
|
---|
| 59 | * cgi the init method is called only once - the first time the servlet classes
|
---|
| 60 | * are loaded. Each time a request comes in to the servlet, the session() method
|
---|
| 61 | * is called in a new thread (calls doGet/doPut etc) takes the a=p&p=home type
|
---|
| 62 | * args and builds a simple request to send to its receptionist, which returns a
|
---|
| 63 | * result in html, cos output=html is set in the request
|
---|
| 64 | *
|
---|
| 65 | * 18/Jul/07 xiao modify to make the cached parameters collection-specific. Most
|
---|
| 66 | * of the work is done in doGet(), except adding an inner class
|
---|
| 67 | * UserSessionCache.
|
---|
| 68 | *
|
---|
| 69 | * @see Receptionist
|
---|
| 70 | */
|
---|
[25717] | 71 | public class LibraryServlet extends BaseGreenstoneServlet
|
---|
[24753] | 72 | {
|
---|
[24019] | 73 | /** the receptionist to send messages to */
|
---|
[24753] | 74 | protected Receptionist recept = null;
|
---|
[18223] | 75 |
|
---|
[24753] | 76 | /**
|
---|
| 77 | * the default language - is specified by setting a servlet param, otherwise
|
---|
| 78 | * DEFAULT_LANG is used
|
---|
| 79 | */
|
---|
| 80 | protected String default_lang = null;
|
---|
[18223] | 81 |
|
---|
[24019] | 82 | /** Whether or not client-side XSLT support should be exposed */
|
---|
| 83 | protected boolean supports_client_xslt = false;
|
---|
[18223] | 84 |
|
---|
[24753] | 85 | /**
|
---|
| 86 | * The default default - used if a default lang is not specified in the
|
---|
| 87 | * servlet params
|
---|
| 88 | */
|
---|
[24019] | 89 | protected final String DEFAULT_LANG = "en";
|
---|
[18223] | 90 |
|
---|
[24019] | 91 | /** container Document to create XML Nodes */
|
---|
[24753] | 92 | protected Document doc = null;
|
---|
[14498] | 93 |
|
---|
[24019] | 94 | /** a converter class to parse XML and create Docs */
|
---|
[24753] | 95 | protected XMLConverter converter = null;
|
---|
[6301] | 96 |
|
---|
[24753] | 97 | /**
|
---|
| 98 | * the cgi stuff - the Receptionist can add new args to this
|
---|
| 99 | *
|
---|
| 100 | * its used by the servlet to determine what args to save
|
---|
| 101 | */
|
---|
[24019] | 102 | protected GSParams params = null;
|
---|
[12021] | 103 |
|
---|
[24753] | 104 | /**
|
---|
| 105 | * user id - new one per session. This doesn't work if session state is
|
---|
| 106 | * saved between restarts - this requires this value to be saved too.
|
---|
| 107 | */
|
---|
[24019] | 108 | protected int next_user_id = 0;
|
---|
[18223] | 109 |
|
---|
[24753] | 110 | /**
|
---|
| 111 | * a hash that contains all the active session IDs mapped to the cached
|
---|
| 112 | * items It is updated whenever the whole site or a particular collection is
|
---|
| 113 | * reconfigured using the command a=s&sa=c or a=s&sa=c&c=xxx It is in the
|
---|
| 114 | * form: sid -> (UserSessionCache object)
|
---|
| 115 | */
|
---|
[25635] | 116 | protected Hashtable<String, UserSessionCache> session_ids_table = new Hashtable<String, UserSessionCache>();
|
---|
[25128] | 117 |
|
---|
[24753] | 118 | /**
|
---|
| 119 | * the maximum interval that the cached info remains in session_ids_table
|
---|
| 120 | * (in seconds) This is set in web.xml
|
---|
| 121 | */
|
---|
[24019] | 122 | protected int session_expiration = 1800;
|
---|
[13122] | 123 |
|
---|
[24019] | 124 | static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
|
---|
[18223] | 125 |
|
---|
[24753] | 126 | /** initialise the servlet */
|
---|
| 127 | public void init(ServletConfig config) throws ServletException
|
---|
| 128 | {
|
---|
[24019] | 129 | // always call super.init;
|
---|
| 130 | super.init(config);
|
---|
| 131 | // disable preferences - does this work anyway??
|
---|
| 132 | //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
|
---|
[24753] | 133 |
|
---|
[24019] | 134 | String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME);
|
---|
| 135 | String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME);
|
---|
[24753] | 136 |
|
---|
| 137 | String allowXslt = (String) config.getInitParameter(GSConstants.ALLOW_CLIENT_SIDE_XSLT);
|
---|
[24019] | 138 | supports_client_xslt = allowXslt != null && allowXslt.equals("true");
|
---|
[24753] | 139 |
|
---|
[24019] | 140 | this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
|
---|
| 141 | String sess_expire = config.getInitParameter(GSXML.SESSION_EXPIRATION);
|
---|
[24753] | 142 |
|
---|
| 143 | if (sess_expire != null && !sess_expire.equals(""))
|
---|
| 144 | {
|
---|
[24019] | 145 | this.session_expiration = Integer.parseInt(sess_expire);
|
---|
| 146 | }
|
---|
[24753] | 147 |
|
---|
| 148 | if (library_name == null || interface_name == null)
|
---|
| 149 | {
|
---|
[24019] | 150 | // must have this
|
---|
| 151 | System.err.println("initialisation parameters not all set!");
|
---|
| 152 | System.err.println(" you must have libraryname and interfacename");
|
---|
| 153 | System.exit(1);
|
---|
| 154 | }
|
---|
[24753] | 155 |
|
---|
[24019] | 156 | String site_name = config.getInitParameter(GSConstants.SITE_NAME);
|
---|
| 157 | String remote_site_name = null;
|
---|
| 158 | String remote_site_type = null;
|
---|
| 159 | String remote_site_address = null;
|
---|
[24753] | 160 |
|
---|
| 161 | if (site_name == null)
|
---|
| 162 | {
|
---|
[24019] | 163 | // no site, try for communicator
|
---|
| 164 | remote_site_name = config.getInitParameter("remote_site_name");
|
---|
| 165 | remote_site_type = config.getInitParameter("remote_site_type");
|
---|
| 166 | remote_site_address = config.getInitParameter("remote_site_address");
|
---|
[24753] | 167 | if (remote_site_name == null || remote_site_type == null || remote_site_address == null)
|
---|
| 168 | {
|
---|
[24019] | 169 | System.err.println("initialisation paramters not all set!");
|
---|
| 170 | System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
|
---|
| 171 | System.exit(1);
|
---|
| 172 | }
|
---|
| 173 | }
|
---|
[24753] | 174 |
|
---|
| 175 | if (this.default_lang == null)
|
---|
| 176 | {
|
---|
[24019] | 177 | // choose english
|
---|
| 178 | this.default_lang = DEFAULT_LANG;
|
---|
| 179 | }
|
---|
[24753] | 180 |
|
---|
[27617] | 181 | HashMap<String, Object> config_params = new HashMap<String, Object>();
|
---|
[24753] | 182 |
|
---|
[24019] | 183 | config_params.put(GSConstants.LIBRARY_NAME, library_name);
|
---|
[24753] | 184 | config_params.put(GSConstants.INTERFACE_NAME, interface_name);
|
---|
[24019] | 185 | config_params.put(GSConstants.ALLOW_CLIENT_SIDE_XSLT, supports_client_xslt);
|
---|
[24753] | 186 |
|
---|
| 187 | if (site_name != null)
|
---|
| 188 | {
|
---|
[24019] | 189 | config_params.put(GSConstants.SITE_NAME, site_name);
|
---|
| 190 | }
|
---|
| 191 | this.converter = new XMLConverter();
|
---|
| 192 | this.doc = this.converter.newDOM();
|
---|
[24753] | 193 |
|
---|
[24019] | 194 | // the receptionist -the servlet will talk to this
|
---|
[24753] | 195 | String recept_name = (String) config.getInitParameter("receptionist_class");
|
---|
| 196 | if (recept_name == null)
|
---|
| 197 | {
|
---|
[24019] | 198 | this.recept = new DefaultReceptionist();
|
---|
[24753] | 199 | }
|
---|
| 200 | else
|
---|
| 201 | {
|
---|
| 202 | try
|
---|
| 203 | {
|
---|
| 204 | this.recept = (Receptionist) Class.forName("org.greenstone.gsdl3.core." + recept_name).newInstance();
|
---|
| 205 | }
|
---|
| 206 | catch (Exception e)
|
---|
| 207 | { // cant use this new one, so use normal one
|
---|
| 208 | System.err.println("LibraryServlet configure exception when trying to use a new Receptionist " + recept_name + ": " + e.getMessage());
|
---|
[24019] | 209 | e.printStackTrace();
|
---|
| 210 | this.recept = new DefaultReceptionist();
|
---|
| 211 | }
|
---|
| 212 | }
|
---|
| 213 | this.recept.setConfigParams(config_params);
|
---|
[24753] | 214 |
|
---|
[24019] | 215 | // the receptionist uses a MessageRouter or Communicator to send its requests to. We either create a MessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to teh Receptionist, and the servlet never talks to it again.directly.
|
---|
[24753] | 216 | if (site_name != null)
|
---|
| 217 | {
|
---|
| 218 | String mr_name = (String) config.getInitParameter("messagerouter_class");
|
---|
[24019] | 219 | MessageRouter message_router = null;
|
---|
[24753] | 220 | if (mr_name == null)
|
---|
| 221 | { // just use the normal MR
|
---|
[24019] | 222 | message_router = new MessageRouter();
|
---|
[24753] | 223 | }
|
---|
| 224 | else
|
---|
| 225 | { // try the specified one
|
---|
| 226 | try
|
---|
| 227 | {
|
---|
| 228 | message_router = (MessageRouter) Class.forName("org.greenstone.gsdl3.core." + mr_name).newInstance();
|
---|
| 229 | }
|
---|
| 230 | catch (Exception e)
|
---|
| 231 | { // cant use this new one, so use normal one
|
---|
| 232 | System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter " + mr_name + ": " + e.getMessage());
|
---|
[24019] | 233 | e.printStackTrace();
|
---|
| 234 | message_router = new MessageRouter();
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
[24753] | 237 |
|
---|
[24019] | 238 | message_router.setSiteName(site_name);
|
---|
| 239 | message_router.setLibraryName(library_name);
|
---|
| 240 | message_router.configure();
|
---|
| 241 | this.recept.setMessageRouter(message_router);
|
---|
[24753] | 242 | }
|
---|
| 243 | else
|
---|
| 244 | {
|
---|
[24019] | 245 | // talking to a remote site, create a communicator
|
---|
| 246 | Communicator communicator = null;
|
---|
| 247 | // we need to create the XML to configure the communicator
|
---|
| 248 | Element site_elem = this.doc.createElement(GSXML.SITE_ELEM);
|
---|
| 249 | site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
|
---|
| 250 | site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
|
---|
| 251 | site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
|
---|
[24753] | 252 |
|
---|
| 253 | if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
|
---|
| 254 | {
|
---|
[24019] | 255 | communicator = new SOAPCommunicator();
|
---|
[24753] | 256 | }
|
---|
| 257 | else
|
---|
| 258 | {
|
---|
| 259 | System.err.println("LibraryServlet.init Error: invalid Communicator type: " + remote_site_type);
|
---|
[24019] | 260 | System.exit(1);
|
---|
| 261 | }
|
---|
[24753] | 262 |
|
---|
| 263 | if (!communicator.configure(site_elem))
|
---|
| 264 | {
|
---|
[24019] | 265 | System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
|
---|
| 266 | System.exit(1);
|
---|
| 267 | }
|
---|
| 268 | this.recept.setMessageRouter(communicator);
|
---|
| 269 | }
|
---|
[24753] | 270 |
|
---|
[24019] | 271 | // the params arg thingy
|
---|
[24753] | 272 |
|
---|
| 273 | String params_name = (String) config.getInitParameter("params_class");
|
---|
| 274 | if (params_name == null)
|
---|
| 275 | {
|
---|
[24019] | 276 | this.params = new GSParams();
|
---|
[24753] | 277 | }
|
---|
| 278 | else
|
---|
| 279 | {
|
---|
| 280 | try
|
---|
| 281 | {
|
---|
| 282 | this.params = (GSParams) Class.forName("org.greenstone.gsdl3.util." + params_name).newInstance();
|
---|
| 283 | }
|
---|
| 284 | catch (Exception e)
|
---|
| 285 | {
|
---|
| 286 | System.err.println("LibraryServlet configure exception when trying to use a new params thing " + params_name + ": " + e.getMessage());
|
---|
[24019] | 287 | e.printStackTrace();
|
---|
| 288 | this.params = new GSParams();
|
---|
| 289 | }
|
---|
| 290 | }
|
---|
| 291 | // pass it to the receptionist
|
---|
| 292 | this.recept.setParams(this.params);
|
---|
| 293 | this.recept.configure();
|
---|
[24753] | 294 |
|
---|
[25257] | 295 | //Allow the message router and the document to be accessed from anywhere in this servlet context
|
---|
| 296 | this.getServletContext().setAttribute("GSRouter", this.recept.getMessageRouter());
|
---|
| 297 | this.getServletContext().setAttribute("GSDocument", this.doc);
|
---|
[24019] | 298 | }
|
---|
[18223] | 299 |
|
---|
[24753] | 300 | private void logUsageInfo(HttpServletRequest request)
|
---|
| 301 | {
|
---|
| 302 | String usageInfo = "";
|
---|
[14524] | 303 |
|
---|
[24019] | 304 | //session-info: get params stored in the session
|
---|
| 305 | HttpSession session = request.getSession(true);
|
---|
| 306 | Enumeration attributeNames = session.getAttributeNames();
|
---|
[24753] | 307 | while (attributeNames.hasMoreElements())
|
---|
| 308 | {
|
---|
| 309 | String name = (String) attributeNames.nextElement();
|
---|
| 310 | usageInfo += name + "=" + session.getAttribute(name) + " ";
|
---|
[24019] | 311 | }
|
---|
[24753] | 312 |
|
---|
[24019] | 313 | //logged info = general-info + session-info
|
---|
[24753] | 314 | usageInfo = request.getServletPath() + " " + //serlvet
|
---|
| 315 | "[" + request.getQueryString() + "]" + " " + //the query string
|
---|
| 316 | "[" + usageInfo.trim() + "]" + " " + // params stored in a session
|
---|
| 317 | request.getRemoteAddr() + " " + //remote address
|
---|
| 318 | request.getRequestedSessionId() + " " + //session id
|
---|
| 319 | request.getHeader("user-agent") + " "; //the remote brower info
|
---|
| 320 |
|
---|
[24019] | 321 | logger.info(usageInfo);
|
---|
[24753] | 322 |
|
---|
[24019] | 323 | }
|
---|
[23790] | 324 |
|
---|
[24753] | 325 | public class UserSessionCache implements HttpSessionBindingListener
|
---|
| 326 | {
|
---|
[24019] | 327 | String session_id = "";
|
---|
[24753] | 328 |
|
---|
| 329 | /**
|
---|
| 330 | * a hash that maps the session ID to a hashtable that maps the
|
---|
| 331 | * coll_name to its parameters coll_name -> Hashtable (param_name ->
|
---|
| 332 | * param_value)
|
---|
| 333 | */
|
---|
[25635] | 334 | protected Hashtable<String, Hashtable<String, String>> coll_name_params_table = null;
|
---|
[24753] | 335 |
|
---|
[25635] | 336 | public UserSessionCache(String id, Hashtable<String, Hashtable<String, String>> table)
|
---|
[24753] | 337 | {
|
---|
| 338 | session_id = id;
|
---|
| 339 | coll_name_params_table = (table == null) ? new Hashtable() : table;
|
---|
[24019] | 340 | }
|
---|
[23790] | 341 |
|
---|
[24753] | 342 | protected void cleanupCache(String coll_name)
|
---|
| 343 | {
|
---|
| 344 | if (coll_name_params_table.containsKey(coll_name))
|
---|
| 345 | {
|
---|
[24019] | 346 | coll_name_params_table.remove(coll_name);
|
---|
| 347 | }
|
---|
| 348 | }
|
---|
| 349 |
|
---|
[25635] | 350 | protected Hashtable<String, Hashtable<String, String>> getParamsTable()
|
---|
[24753] | 351 | {
|
---|
[24019] | 352 | return coll_name_params_table;
|
---|
| 353 | }
|
---|
| 354 |
|
---|
[24753] | 355 | public void valueBound(HttpSessionBindingEvent event)
|
---|
| 356 | {
|
---|
[24019] | 357 | // Do nothing
|
---|
| 358 | }
|
---|
| 359 |
|
---|
[24753] | 360 | public void valueUnbound(HttpSessionBindingEvent event)
|
---|
| 361 | {
|
---|
| 362 | if (session_ids_table.containsKey(session_id))
|
---|
| 363 | {
|
---|
[24019] | 364 | session_ids_table.remove(session_id);
|
---|
| 365 | }
|
---|
| 366 | }
|
---|
| 367 |
|
---|
[24753] | 368 | public int tableSize()
|
---|
| 369 | {
|
---|
| 370 | return (coll_name_params_table == null) ? 0 : coll_name_params_table.size();
|
---|
[24019] | 371 | }
|
---|
| 372 | }
|
---|
[26210] | 373 |
|
---|
[25761] | 374 | public void destroy()
|
---|
| 375 | {
|
---|
| 376 | recept.cleanUp();
|
---|
| 377 | }
|
---|
[24019] | 378 |
|
---|
[27617] | 379 | public void doGetOrPost(HttpServletRequest request, HttpServletResponse response, Map<String, String[]> queryMap) throws ServletException, IOException
|
---|
[24753] | 380 | {
|
---|
| 381 | logUsageInfo(request);
|
---|
[25092] | 382 |
|
---|
[25054] | 383 | if (queryMap != null)
|
---|
[24753] | 384 | {
|
---|
[25054] | 385 | Iterator<String> queryIter = queryMap.keySet().iterator();
|
---|
[24019] | 386 | boolean redirect = false;
|
---|
| 387 | String href = null;
|
---|
| 388 | String rl = null;
|
---|
[25304] | 389 | String el = null;
|
---|
[27617] | 390 |
|
---|
[25054] | 391 | while (queryIter.hasNext())
|
---|
[24753] | 392 | {
|
---|
[25054] | 393 | String q = queryIter.next();
|
---|
[25304] | 394 | if (q.equals(GSParams.EXTERNAL_LINK_TYPE))
|
---|
[24753] | 395 | {
|
---|
[25351] | 396 | el = queryMap.get(q)[0];
|
---|
[24753] | 397 | }
|
---|
[25304] | 398 | else if (q.equals(GSParams.HREF))
|
---|
[24753] | 399 | {
|
---|
[25054] | 400 | href = queryMap.get(q)[0];
|
---|
[24019] | 401 | href = StringUtils.replace(href, "%2f", "/");
|
---|
| 402 | href = StringUtils.replace(href, "%7e", "~");
|
---|
| 403 | href = StringUtils.replace(href, "%3f", "?");
|
---|
| 404 | href = StringUtils.replace(href, "%3A", "\\:");
|
---|
| 405 | }
|
---|
[25304] | 406 | else if (q.equals(GSParams.RELATIVE_LINK))
|
---|
[24753] | 407 | {
|
---|
[25054] | 408 | rl = queryMap.get(q)[0];
|
---|
[24753] | 409 | }
|
---|
[24019] | 410 | }
|
---|
| 411 |
|
---|
[25304] | 412 | //if query_string contains "el=direct", an href is specified, and its not a relative link, then the web page will be redirected to the external URl, otherwise a greenstone page with an external URL will be displayed
|
---|
[24019] | 413 | //"rl=0" this is an external link
|
---|
| 414 | //"rl=1" this is an internal link
|
---|
[25304] | 415 | if ((href != null) && (rl.equals("0")))
|
---|
| 416 | {// This is an external link,
|
---|
| 417 |
|
---|
[25351] | 418 | if (el.equals("framed"))
|
---|
| 419 | {
|
---|
| 420 | //TODO **** how best to change to a=p&sa=html&c=collection&url=href
|
---|
| 421 | // response.setContentType("text/xml");
|
---|
| 422 | //response.sendRedirect("http://localhost:8383/greenstone3/gs3library?a=p&sa=html&c=external&url="+href);
|
---|
| 423 | }
|
---|
| 424 | else
|
---|
| 425 | {
|
---|
| 426 | // el = '' or direct
|
---|
| 427 | //the web page is re-directed to the external URL (&el=&rl=0&href="http://...")
|
---|
| 428 | response.setContentType("text/xml");
|
---|
| 429 | response.sendRedirect(href);
|
---|
| 430 | }
|
---|
[24019] | 431 | }
|
---|
| 432 | }
|
---|
[24753] | 433 |
|
---|
[24019] | 434 | // Nested Diagnostic Configurator to identify the client for
|
---|
[24753] | 435 | HttpSession session = request.getSession(true);
|
---|
[24019] | 436 | session.setMaxInactiveInterval(session_expiration);
|
---|
[24753] | 437 | String uid = (String) session.getAttribute(GSXML.USER_ID_ATT);
|
---|
| 438 | if (uid == null)
|
---|
| 439 | {
|
---|
| 440 | uid = "" + getNextUserId();
|
---|
| 441 | session.setAttribute(GSXML.USER_ID_ATT, uid);
|
---|
[24019] | 442 | }
|
---|
[24962] | 443 |
|
---|
[24753] | 444 | request.setCharacterEncoding("UTF-8");
|
---|
| 445 | response.setContentType("text/html;charset=UTF-8");
|
---|
| 446 | PrintWriter out = response.getWriter();
|
---|
| 447 |
|
---|
[27617] | 448 | String lang = getFirstParam(GSParams.LANGUAGE, queryMap);
|
---|
[24753] | 449 | if (lang == null || lang.equals(""))
|
---|
| 450 | {
|
---|
[24019] | 451 | // try the session cached lang
|
---|
[24753] | 452 | lang = (String) session.getAttribute(GSParams.LANGUAGE);
|
---|
| 453 | if (lang == null || lang.equals(""))
|
---|
| 454 | {
|
---|
[24019] | 455 | // still not set, use the default
|
---|
| 456 | lang = this.default_lang;
|
---|
| 457 | }
|
---|
| 458 | }
|
---|
[24993] | 459 | UserContext userContext = new UserContext();
|
---|
| 460 | userContext.setLanguage(lang);
|
---|
| 461 | userContext.setUserID(uid);
|
---|
[24753] | 462 |
|
---|
[27074] | 463 | if (request.getAuthType() != null)
|
---|
| 464 | {
|
---|
[27617] | 465 | //Get the username
|
---|
| 466 | userContext.setUsername(request.getUserPrincipal().getName());
|
---|
| 467 |
|
---|
[27074] | 468 | //Get the groups for the user
|
---|
| 469 | Element acquireGroupMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
| 470 | Element acquireGroupRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, "GetUserInformation", userContext);
|
---|
| 471 | acquireGroupMessage.appendChild(acquireGroupRequest);
|
---|
| 472 |
|
---|
| 473 | Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 474 | acquireGroupRequest.appendChild(paramList);
|
---|
[27617] | 475 | paramList.appendChild(GSXML.createParameter(this.doc, GSXML.USERNAME_ATT, request.getUserPrincipal().getName()));
|
---|
[27074] | 476 |
|
---|
| 477 | Element aquireGroupsResponseMessage = (Element) this.recept.process(acquireGroupMessage);
|
---|
| 478 | Element aquireGroupsResponse = (Element) GSXML.getChildByTagName(aquireGroupsResponseMessage, GSXML.RESPONSE_ELEM);
|
---|
| 479 | Element param_list = (Element) GSXML.getChildByTagName(aquireGroupsResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 480 |
|
---|
| 481 | if (param_list != null)
|
---|
| 482 | {
|
---|
| 483 | HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
|
---|
| 484 | String groups = (String) params.get("groups");
|
---|
| 485 | userContext.setGroups(groups.split(","));
|
---|
| 486 | }
|
---|
| 487 | }
|
---|
| 488 |
|
---|
[24019] | 489 | // set the lang in the session
|
---|
[24753] | 490 | session.setAttribute(GSParams.LANGUAGE, lang);
|
---|
| 491 |
|
---|
[27617] | 492 | String output = getFirstParam(GSParams.OUTPUT, queryMap);
|
---|
[24753] | 493 | if (output == null || output.equals(""))
|
---|
| 494 | {
|
---|
[24019] | 495 | output = "html"; // uses html by default
|
---|
| 496 | }
|
---|
[24753] | 497 |
|
---|
[24019] | 498 | // If server output, force a switch to traditional interface
|
---|
| 499 | //output = (output.equals("server")) ? "html" : output;
|
---|
[24753] | 500 |
|
---|
[24019] | 501 | // Force change the output mode if client-side XSLT is supported - server vs. client
|
---|
| 502 | // BUT only if the library allows client-side transforms
|
---|
[24753] | 503 | if (supports_client_xslt)
|
---|
| 504 | {
|
---|
[24019] | 505 | // MUST be done before the xml_message is built
|
---|
| 506 | Cookie[] cookies = request.getCookies();
|
---|
| 507 | Cookie xsltCookie = null;
|
---|
[24753] | 508 |
|
---|
[24019] | 509 | // The client has cookies enabled and a value set - use it!
|
---|
[24753] | 510 | if (cookies != null)
|
---|
| 511 | {
|
---|
| 512 | for (Cookie c : cookies)
|
---|
| 513 | {
|
---|
| 514 | if (c.getName().equals("supportsXSLT"))
|
---|
| 515 | {
|
---|
[24019] | 516 | xsltCookie = c;
|
---|
| 517 | break;
|
---|
| 518 | }
|
---|
[23790] | 519 | }
|
---|
[24019] | 520 | output = (xsltCookie != null && xsltCookie.getValue().equals("true") && output.equals("html")) ? "xsltclient" : output;
|
---|
[23790] | 521 | }
|
---|
| 522 | }
|
---|
[24753] | 523 |
|
---|
[24019] | 524 | // the request to the receptionist
|
---|
[24753] | 525 | Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
[24993] | 526 | Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
|
---|
[24753] | 527 | xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
|
---|
| 528 |
|
---|
| 529 | xml_message.appendChild(xml_request);
|
---|
| 530 |
|
---|
[27617] | 531 | String action = getFirstParam(GSParams.ACTION, queryMap);
|
---|
| 532 | String subaction = getFirstParam(GSParams.SUBACTION, queryMap);
|
---|
| 533 | String collection = getFirstParam(GSParams.COLLECTION, queryMap);
|
---|
| 534 | String document = getFirstParam(GSParams.DOCUMENT, queryMap);
|
---|
| 535 | String service = getFirstParam(GSParams.SERVICE, queryMap);
|
---|
[13122] | 536 |
|
---|
[24019] | 537 | // We clean up the cache session_ids_table if system
|
---|
| 538 | // commands are issued (and also don't need to do caching for this request)
|
---|
| 539 | boolean should_cache = true;
|
---|
[25304] | 540 | if (action != null && action.equals(GSParams.SYSTEM_ACTION))
|
---|
[24753] | 541 | {
|
---|
[24019] | 542 | should_cache = false;
|
---|
[16938] | 543 |
|
---|
[24019] | 544 | // we may want to remove all collection cache info, or just a specific collection
|
---|
[24753] | 545 | boolean clean_all = true;
|
---|
[24019] | 546 | String clean_collection = null;
|
---|
| 547 | // system commands are to activate/deactivate stuff
|
---|
| 548 | // collection param is in the sc parameter.
|
---|
| 549 | // don't like the fact that it is hard coded here
|
---|
[27617] | 550 | String coll = getFirstParam(GSParams.SYSTEM_CLUSTER, queryMap);
|
---|
[24753] | 551 | if (coll != null && !coll.equals(""))
|
---|
| 552 | {
|
---|
[24019] | 553 | clean_all = false;
|
---|
| 554 | clean_collection = coll;
|
---|
[24753] | 555 | }
|
---|
| 556 | else
|
---|
| 557 | {
|
---|
[24019] | 558 | // check other system types
|
---|
[24753] | 559 | if (subaction.equals("a") || subaction.equals("d"))
|
---|
| 560 | {
|
---|
[27617] | 561 | String module_name = getFirstParam("sn", queryMap);
|
---|
[24753] | 562 | if (module_name != null && !module_name.equals(""))
|
---|
| 563 | {
|
---|
[24019] | 564 | clean_all = false;
|
---|
| 565 | clean_collection = module_name;
|
---|
| 566 | }
|
---|
| 567 | }
|
---|
| 568 | }
|
---|
[24753] | 569 | if (clean_all)
|
---|
| 570 | {
|
---|
[25635] | 571 | session_ids_table = new Hashtable<String, UserSessionCache>();
|
---|
[24019] | 572 | session.removeAttribute(GSXML.USER_SESSION_CACHE_ATT);
|
---|
[24753] | 573 | }
|
---|
| 574 | else
|
---|
| 575 | {
|
---|
[24019] | 576 | // just clean up info for clean_collection
|
---|
[25635] | 577 | ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(session_ids_table.values());
|
---|
[24753] | 578 | for (int i = 0; i < cache_list.size(); i++)
|
---|
| 579 | {
|
---|
[25635] | 580 | UserSessionCache cache = cache_list.get(i);
|
---|
[24019] | 581 | cache.cleanupCache(clean_collection);
|
---|
| 582 | }
|
---|
[24753] | 583 |
|
---|
[24019] | 584 | }
|
---|
| 585 | }
|
---|
[24753] | 586 |
|
---|
[24019] | 587 | // cache_key is the collection name, or service name
|
---|
| 588 | String cache_key = collection;
|
---|
[24753] | 589 | if (cache_key == null || cache_key.equals(""))
|
---|
| 590 | {
|
---|
[24019] | 591 | cache_key = service;
|
---|
| 592 | }
|
---|
[24753] | 593 |
|
---|
[24019] | 594 | // logger.info("should_cache= " + should_cache);
|
---|
[16938] | 595 |
|
---|
[24019] | 596 | //clear the collection-specific cache in the session, since we have no way to know whether this session is
|
---|
| 597 | //about the same collection as the last session or not.
|
---|
| 598 | Enumeration attributeNames = session.getAttributeNames();
|
---|
[24753] | 599 | while (attributeNames.hasMoreElements())
|
---|
| 600 | {
|
---|
| 601 | String name = (String) attributeNames.nextElement();
|
---|
| 602 | if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
|
---|
| 603 | {
|
---|
[24019] | 604 | session.removeAttribute(name);
|
---|
| 605 | }
|
---|
| 606 | }
|
---|
[24753] | 607 |
|
---|
[24019] | 608 | UserSessionCache session_cache = null;
|
---|
[25635] | 609 | Hashtable<String, Hashtable<String, String>> param_table = null;
|
---|
| 610 | Hashtable<String, String> table = null;
|
---|
[24019] | 611 | String sid = session.getId();
|
---|
[24753] | 612 | if (should_cache == true && cache_key != null && !cache_key.equals(""))
|
---|
| 613 | {
|
---|
| 614 | if (session_ids_table.containsKey(sid))
|
---|
| 615 | {
|
---|
[25635] | 616 | session_cache = session_ids_table.get(sid);
|
---|
[24019] | 617 | param_table = session_cache.getParamsTable();
|
---|
| 618 | logger.info("collections in table: " + tableToString(param_table));
|
---|
[24753] | 619 | if (param_table.containsKey(cache_key))
|
---|
| 620 | {
|
---|
[24019] | 621 | //logger.info("existing table: " + collection);
|
---|
[25635] | 622 | table = param_table.get(cache_key);
|
---|
[24753] | 623 | }
|
---|
| 624 | else
|
---|
| 625 | {
|
---|
[25635] | 626 | table = new Hashtable<String, String>();
|
---|
[24019] | 627 | param_table.put(cache_key, table);
|
---|
| 628 | //logger.info("new table: " + collection);
|
---|
| 629 | }
|
---|
[24753] | 630 | }
|
---|
| 631 | else
|
---|
| 632 | {
|
---|
[25635] | 633 | param_table = new Hashtable<String, Hashtable<String, String>>();
|
---|
| 634 | table = new Hashtable<String, String>();
|
---|
[24019] | 635 | param_table.put(cache_key, table);
|
---|
| 636 | session_cache = new UserSessionCache(sid, param_table);
|
---|
| 637 | session_ids_table.put(sid, session_cache);
|
---|
| 638 | session.setAttribute(GSXML.USER_SESSION_CACHE_ATT, session_cache);
|
---|
| 639 | //logger.info("new session id");
|
---|
| 640 | }
|
---|
| 641 | }
|
---|
[6301] | 642 |
|
---|
[24753] | 643 | if (action == null || action.equals(""))
|
---|
| 644 | {
|
---|
[24019] | 645 | // should we do all the following stuff if using default page?
|
---|
| 646 | // display the home page - the default page
|
---|
[24753] | 647 | xml_request.setAttribute(GSXML.ACTION_ATT, "p");
|
---|
| 648 | xml_request.setAttribute(GSXML.SUBACTION_ATT, PageAction.HOME_PAGE);
|
---|
[24019] | 649 | }
|
---|
[24753] | 650 | else
|
---|
| 651 | {
|
---|
| 652 | xml_request.setAttribute(GSXML.ACTION_ATT, action);
|
---|
| 653 | if (subaction != null)
|
---|
| 654 | {
|
---|
| 655 | xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
|
---|
[24019] | 656 | }
|
---|
[24753] | 657 |
|
---|
[24019] | 658 | // create the param list for the greenstone request - includes
|
---|
| 659 | // the params from the current request and any others from the saved session
|
---|
[24753] | 660 | Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 661 | xml_request.appendChild(xml_param_list);
|
---|
| 662 |
|
---|
[25257] | 663 | for (String name : queryMap.keySet())
|
---|
[24753] | 664 | {
|
---|
| 665 | if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT))
|
---|
| 666 | {// we have already dealt with these
|
---|
| 667 |
|
---|
| 668 | String value = "";
|
---|
[27617] | 669 | String[] values = queryMap.get(name);
|
---|
[24019] | 670 | value = values[0];
|
---|
[24753] | 671 | if (values.length > 1)
|
---|
| 672 | {
|
---|
| 673 | for (int i = 1; i < values.length; i++)
|
---|
| 674 | {
|
---|
| 675 | value += "," + values[i];
|
---|
[24019] | 676 | }
|
---|
| 677 | }
|
---|
| 678 | // either add it to the param list straight away, or save it to the session and add it later
|
---|
[24753] | 679 | if (this.params.shouldSave(name) && table != null)
|
---|
| 680 | {
|
---|
[24019] | 681 | table.put(name, value);
|
---|
| 682 | }
|
---|
[24753] | 683 | else
|
---|
| 684 | {
|
---|
| 685 | Element param = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 686 | param.setAttribute(GSXML.NAME_ATT, name);
|
---|
| 687 | param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
|
---|
| 688 | xml_param_list.appendChild(param);
|
---|
| 689 | }
|
---|
[24019] | 690 | }
|
---|
| 691 | }
|
---|
| 692 | //put everything in the table into the session
|
---|
| 693 | // do we need to do this? why not just put from table into param list
|
---|
[24753] | 694 | if (table != null)
|
---|
| 695 | {
|
---|
[25635] | 696 | Enumeration<String> keys = table.keys();
|
---|
[24753] | 697 | while (keys.hasMoreElements())
|
---|
| 698 | {
|
---|
[25635] | 699 | String name = keys.nextElement();
|
---|
| 700 | session.setAttribute(name, table.get(name));
|
---|
[24019] | 701 | }
|
---|
| 702 | }
|
---|
[24753] | 703 |
|
---|
[24019] | 704 | // put in all the params from the session cache
|
---|
[25257] | 705 | Enumeration params = session.getAttributeNames();
|
---|
[24753] | 706 | while (params.hasMoreElements())
|
---|
| 707 | {
|
---|
| 708 | String name = (String) params.nextElement();
|
---|
[18223] | 709 |
|
---|
[24753] | 710 | if (!name.equals(GSXML.USER_SESSION_CACHE_ATT) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
|
---|
| 711 | {
|
---|
| 712 |
|
---|
[24019] | 713 | // lang and uid are stored but we dont want it in the param list cos its already in the request
|
---|
[24753] | 714 | Element param = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 715 | param.setAttribute(GSXML.NAME_ATT, name);
|
---|
| 716 | String value = GSXML.xmlSafe((String) session.getAttribute(name));
|
---|
[18223] | 717 |
|
---|
[24019] | 718 | // ugly hack to undo : escaping
|
---|
| 719 | value = StringUtils.replace(value, "%3A", "\\:");
|
---|
[24753] | 720 | param.setAttribute(GSXML.VALUE_ATT, value);
|
---|
| 721 | xml_param_list.appendChild(param);
|
---|
[24019] | 722 | }
|
---|
| 723 | }
|
---|
| 724 | }
|
---|
[24753] | 725 |
|
---|
[27073] | 726 | if (output.equals("json"))
|
---|
| 727 | {
|
---|
| 728 | response.setContentType("application/json");
|
---|
[26507] | 729 | }
|
---|
| 730 | else if (!output.equals("html") && !output.equals("server") && !output.equals("xsltclient"))
|
---|
[24753] | 731 | {
|
---|
| 732 | response.setContentType("text/xml"); // for now use text
|
---|
[24019] | 733 | }
|
---|
[24753] | 734 |
|
---|
[24019] | 735 | //Add custom HTTP headers if requested
|
---|
[27617] | 736 | String httpHeadersParam = getFirstParam(GSParams.HTTP_HEADER_FIELDS, queryMap);
|
---|
[24118] | 737 | if (httpHeadersParam != null && httpHeadersParam.length() > 0)
|
---|
| 738 | {
|
---|
| 739 | Gson gson = new Gson();
|
---|
[24753] | 740 | Type type = new TypeToken<List<Map<String, String>>>()
|
---|
| 741 | {
|
---|
| 742 | }.getType();
|
---|
| 743 | List<Map<String, String>> httpHeaders = gson.fromJson(httpHeadersParam, type);
|
---|
| 744 | if (httpHeaders != null && httpHeaders.size() > 0)
|
---|
| 745 | {
|
---|
| 746 |
|
---|
| 747 | for (int j = 0; j < httpHeaders.size(); j++)
|
---|
[24019] | 748 | {
|
---|
[25635] | 749 | Map nameValueMap = httpHeaders.get(j);
|
---|
[24753] | 750 | String name = (String) nameValueMap.get("name");
|
---|
| 751 | String value = (String) nameValueMap.get("value");
|
---|
| 752 |
|
---|
| 753 | if (name != null && value != null)
|
---|
[24118] | 754 | {
|
---|
| 755 | response.setHeader(name, value);
|
---|
| 756 | }
|
---|
[24019] | 757 | }
|
---|
| 758 | }
|
---|
| 759 | }
|
---|
[25310] | 760 |
|
---|
[25257] | 761 | String requestedURL = request.getRequestURL().toString();
|
---|
[25351] | 762 | String baseURL = "";
|
---|
| 763 | if (requestedURL.indexOf(this.getServletName()) != -1)
|
---|
| 764 | {
|
---|
| 765 | baseURL = requestedURL.substring(0, requestedURL.indexOf(this.getServletName()));
|
---|
| 766 | xml_request.setAttribute("baseURL", baseURL);
|
---|
| 767 | }
|
---|
| 768 |
|
---|
| 769 | String fullURL;
|
---|
| 770 | if (request.getQueryString() != null)
|
---|
| 771 | {
|
---|
| 772 | fullURL = requestedURL + "?" + request.getQueryString();
|
---|
| 773 | }
|
---|
| 774 | else
|
---|
| 775 | {
|
---|
| 776 | fullURL = requestedURL;
|
---|
| 777 | }
|
---|
| 778 |
|
---|
[25257] | 779 | xml_request.setAttribute("remoteAddress", request.getRemoteAddr());
|
---|
[25351] | 780 | xml_request.setAttribute("fullURL", fullURL.replace("&", "&"));
|
---|
[25310] | 781 |
|
---|
[27617] | 782 | if (!runSecurityChecks(request, xml_request, userContext, out, baseURL, collection, document, queryMap))
|
---|
[25257] | 783 | {
|
---|
| 784 | return;
|
---|
| 785 | }
|
---|
[24753] | 786 |
|
---|
[25257] | 787 | Node xml_result = this.recept.process(xml_message);
|
---|
| 788 | encodeURLs(xml_result, response);
|
---|
| 789 |
|
---|
[26507] | 790 | String xml_string = this.converter.getPrettyString(xml_result);
|
---|
| 791 |
|
---|
[27073] | 792 | if (output.equals("json"))
|
---|
| 793 | {
|
---|
| 794 | try
|
---|
| 795 | {
|
---|
| 796 | JSONObject json_obj = org.json.XML.toJSONObject(xml_string);
|
---|
| 797 |
|
---|
| 798 | out.println(json_obj.toString());
|
---|
| 799 | }
|
---|
| 800 | catch (Exception e)
|
---|
| 801 | {
|
---|
| 802 | e.printStackTrace();
|
---|
| 803 | out.println("Error: failed to convert output XML to JSON format");
|
---|
| 804 | }
|
---|
[26507] | 805 | }
|
---|
[27073] | 806 | else
|
---|
| 807 | {
|
---|
| 808 | out.println(xml_string);
|
---|
[26507] | 809 | }
|
---|
| 810 |
|
---|
[25257] | 811 | displaySize(session_ids_table);
|
---|
[27617] | 812 | }
|
---|
[25257] | 813 |
|
---|
[27617] | 814 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
---|
| 815 | {
|
---|
| 816 | doGetOrPost(request, response, request.getParameterMap());
|
---|
[25257] | 817 | } //end of doGet(HttpServletRequest, HttpServletResponse)
|
---|
| 818 |
|
---|
[27617] | 819 | private boolean runSecurityChecks(HttpServletRequest request, Element xml_request, UserContext userContext, PrintWriter out, String baseURL, String collection, String document, Map<String, String[]> queryMap) throws ServletException
|
---|
[25257] | 820 | {
|
---|
[25092] | 821 | //Check if we need to login or logout
|
---|
[27617] | 822 | String username = getFirstParam("username", queryMap);
|
---|
| 823 | String password = getFirstParam("password", queryMap);
|
---|
| 824 | String logout = getFirstParam("logout", queryMap);
|
---|
[25092] | 825 |
|
---|
| 826 | if (logout != null)
|
---|
| 827 | {
|
---|
| 828 | request.logout();
|
---|
| 829 | }
|
---|
| 830 |
|
---|
| 831 | if (username != null && password != null)
|
---|
| 832 | {
|
---|
[25310] | 833 | //We are changing to another user, so log out first
|
---|
[25092] | 834 | if (request.getAuthType() != null)
|
---|
| 835 | {
|
---|
| 836 | request.logout();
|
---|
| 837 | }
|
---|
[25257] | 838 |
|
---|
[27617] | 839 | //This try/catch block catches when the login request fails (e.g. The user enters an incorrect password).
|
---|
[25129] | 840 | try
|
---|
| 841 | {
|
---|
[27617] | 842 | //Try a global login first
|
---|
| 843 | password = Authentication.hashPassword(password);
|
---|
| 844 | request.login(username, password);
|
---|
[25129] | 845 | }
|
---|
[25257] | 846 | catch (Exception ex)
|
---|
[25129] | 847 | {
|
---|
[27617] | 848 | try
|
---|
| 849 | {
|
---|
| 850 | //If the global login fails then try a site-level login
|
---|
| 851 | String siteName = (String) this.recept.getConfigParams().get(GSConstants.SITE_NAME);
|
---|
| 852 | request.login(siteName + "-" + username, password);
|
---|
| 853 | }
|
---|
| 854 | catch (Exception exc)
|
---|
| 855 | {
|
---|
| 856 | //The user entered in either the wrong username or the wrong password
|
---|
| 857 | Element loginPageMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
| 858 | Element loginPageRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
|
---|
| 859 | loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
|
---|
| 860 | loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
|
---|
| 861 | loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
|
---|
| 862 | loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
|
---|
| 863 | loginPageMessage.appendChild(loginPageRequest);
|
---|
[25129] | 864 |
|
---|
[27617] | 865 | Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 866 | loginPageRequest.appendChild(paramList);
|
---|
[25129] | 867 |
|
---|
[27617] | 868 | Element messageParam = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 869 | messageParam.setAttribute(GSXML.NAME_ATT, "loginMessage");
|
---|
| 870 | messageParam.setAttribute(GSXML.VALUE_ATT, "Either your username or password was incorrect, please try again.");
|
---|
| 871 | paramList.appendChild(messageParam);
|
---|
[25129] | 872 |
|
---|
[27617] | 873 | Element urlParam = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 874 | urlParam.setAttribute(GSXML.NAME_ATT, "redirectURL");
|
---|
| 875 | String queryString = "";
|
---|
| 876 | if (request.getQueryString() != null)
|
---|
| 877 | {
|
---|
| 878 | queryString = "?" + request.getQueryString().replace("&", "&");
|
---|
| 879 | }
|
---|
| 880 | urlParam.setAttribute(GSXML.VALUE_ATT, this.getServletName() + queryString);
|
---|
| 881 | paramList.appendChild(urlParam);
|
---|
[25129] | 882 |
|
---|
[27617] | 883 | Node loginPageResponse = this.recept.process(loginPageMessage);
|
---|
| 884 | out.println(this.converter.getPrettyString(loginPageResponse));
|
---|
[25129] | 885 |
|
---|
[27617] | 886 | return false;
|
---|
| 887 | }
|
---|
[25129] | 888 | }
|
---|
[25092] | 889 | }
|
---|
[25128] | 890 |
|
---|
[25129] | 891 | //If a user is logged in
|
---|
[25128] | 892 | if (request.getAuthType() != null)
|
---|
[25092] | 893 | {
|
---|
[25257] | 894 | Element userInformation = this.doc.createElement(GSXML.USER_INFORMATION_ELEM);
|
---|
[27617] | 895 | userInformation.setAttribute(GSXML.USERNAME_ATT, request.getUserPrincipal().getName());
|
---|
[25128] | 896 |
|
---|
| 897 | Element userInfoMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
| 898 | Element userInfoRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, "GetUserInformation", userContext);
|
---|
| 899 | userInfoMessage.appendChild(userInfoRequest);
|
---|
| 900 |
|
---|
| 901 | Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 902 | userInfoRequest.appendChild(paramList);
|
---|
| 903 |
|
---|
| 904 | Element param = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
[25257] | 905 | param.setAttribute(GSXML.NAME_ATT, GSXML.USERNAME_ATT);
|
---|
[25128] | 906 | param.setAttribute(GSXML.VALUE_ATT, request.getUserPrincipal().getName());
|
---|
| 907 | paramList.appendChild(param);
|
---|
| 908 |
|
---|
| 909 | Element userInformationResponse = (Element) GSXML.getChildByTagName(this.recept.process(userInfoMessage), GSXML.RESPONSE_ELEM);
|
---|
| 910 | Element responseParamList = (Element) GSXML.getChildByTagName(userInformationResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 911 | if (responseParamList == null)
|
---|
| 912 | {
|
---|
| 913 | logger.error("Can't get the groups for user " + request.getUserPrincipal().getName());
|
---|
| 914 | }
|
---|
[25257] | 915 | else
|
---|
| 916 | {
|
---|
[25635] | 917 | HashMap<String, Serializable> responseParams = GSXML.extractParams(responseParamList, true);
|
---|
[25257] | 918 | String groups = (String) responseParams.get(GSXML.GROUPS_ATT);
|
---|
[25128] | 919 |
|
---|
[25257] | 920 | userInformation.setAttribute(GSXML.GROUPS_ATT, groups);
|
---|
| 921 | xml_request.appendChild(userInformation);
|
---|
| 922 | }
|
---|
[25092] | 923 | }
|
---|
| 924 |
|
---|
| 925 | //If we are in a collection-related page then make sure this user is allowed to access it
|
---|
| 926 | if (collection != null && !collection.equals(""))
|
---|
| 927 | {
|
---|
| 928 | //Get the security info for this collection
|
---|
| 929 | Element securityMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
| 930 | Element securityRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, collection, userContext);
|
---|
| 931 | securityMessage.appendChild(securityRequest);
|
---|
| 932 | if (document != null && !document.equals(""))
|
---|
| 933 | {
|
---|
[25257] | 934 | securityRequest.setAttribute(GSXML.NODE_OID, document);
|
---|
[25092] | 935 | }
|
---|
| 936 |
|
---|
| 937 | Element securityResponse = (Element) GSXML.getChildByTagName(this.recept.process(securityMessage), GSXML.RESPONSE_ELEM);
|
---|
[26210] | 938 | if (securityResponse == null)
|
---|
| 939 | {
|
---|
| 940 | return false;
|
---|
| 941 | }
|
---|
| 942 |
|
---|
[25092] | 943 | ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
|
---|
| 944 |
|
---|
| 945 | //If guests are not allowed to access this page then check to see if the user is in a group that is allowed to access the page
|
---|
| 946 | if (!groups.contains(""))
|
---|
| 947 | {
|
---|
| 948 | boolean found = false;
|
---|
| 949 | for (String group : groups)
|
---|
| 950 | {
|
---|
| 951 | if (request.isUserInRole(group))
|
---|
| 952 | {
|
---|
| 953 | found = true;
|
---|
| 954 | break;
|
---|
| 955 | }
|
---|
| 956 | }
|
---|
| 957 |
|
---|
| 958 | //The current user is not allowed to access the page so produce a login page
|
---|
| 959 | if (!found)
|
---|
| 960 | {
|
---|
| 961 | Element loginPageMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
|
---|
| 962 | Element loginPageRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
|
---|
| 963 | loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
|
---|
| 964 | loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
|
---|
| 965 | loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
|
---|
[25257] | 966 | loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
|
---|
[25092] | 967 | loginPageMessage.appendChild(loginPageRequest);
|
---|
| 968 |
|
---|
| 969 | Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
|
---|
| 970 | loginPageRequest.appendChild(paramList);
|
---|
[25128] | 971 |
|
---|
[25092] | 972 | Element messageParam = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 973 | messageParam.setAttribute(GSXML.NAME_ATT, "loginMessage");
|
---|
[25128] | 974 | if (request.getAuthType() == null)
|
---|
[25092] | 975 | {
|
---|
| 976 | messageParam.setAttribute(GSXML.VALUE_ATT, "Please log in to view this page");
|
---|
| 977 | }
|
---|
| 978 | else
|
---|
| 979 | {
|
---|
[25128] | 980 | messageParam.setAttribute(GSXML.VALUE_ATT, "You are not in the correct group to view this page, would you like to log in as a different user?");
|
---|
[25092] | 981 | }
|
---|
| 982 | paramList.appendChild(messageParam);
|
---|
[25128] | 983 |
|
---|
[25092] | 984 | Element urlParam = this.doc.createElement(GSXML.PARAM_ELEM);
|
---|
| 985 | urlParam.setAttribute(GSXML.NAME_ATT, "redirectURL");
|
---|
[25351] | 986 | if (request.getQueryString() != null && request.getQueryString().length() > 0)
|
---|
| 987 | {
|
---|
[25425] | 988 | urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL() + "?" + request.getQueryString().replace("&", "&"));
|
---|
[25351] | 989 | }
|
---|
| 990 | else
|
---|
| 991 | {
|
---|
[25425] | 992 | urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL().toString());
|
---|
[25351] | 993 | }
|
---|
[25092] | 994 | paramList.appendChild(urlParam);
|
---|
| 995 |
|
---|
| 996 | Node loginPageResponse = this.recept.process(loginPageMessage);
|
---|
| 997 | out.println(this.converter.getPrettyString(loginPageResponse));
|
---|
| 998 |
|
---|
[25257] | 999 | return false;
|
---|
[25092] | 1000 | }
|
---|
| 1001 | }
|
---|
| 1002 | }
|
---|
[25257] | 1003 | return true;
|
---|
| 1004 | }
|
---|
[25310] | 1005 |
|
---|
[24019] | 1006 | //a debugging method
|
---|
[25635] | 1007 | private void displaySize(Hashtable<String, UserSessionCache> table)
|
---|
[24753] | 1008 | {
|
---|
| 1009 | if (table == null)
|
---|
| 1010 | {
|
---|
[24019] | 1011 | logger.info("cached table is null");
|
---|
| 1012 | return;
|
---|
| 1013 | }
|
---|
[24753] | 1014 | if (table.size() == 0)
|
---|
| 1015 | {
|
---|
[24019] | 1016 | logger.info("cached table size is zero");
|
---|
| 1017 | return;
|
---|
| 1018 | }
|
---|
| 1019 | int num_cached_coll = 0;
|
---|
[25635] | 1020 | ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(table.values());
|
---|
[24753] | 1021 | for (int i = 0; i < cache_list.size(); i++)
|
---|
| 1022 | {
|
---|
[25635] | 1023 | num_cached_coll += cache_list.get(i).tableSize();
|
---|
[24019] | 1024 | }
|
---|
| 1025 | logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
|
---|
| 1026 | }
|
---|
[18223] | 1027 |
|
---|
[24019] | 1028 | /** merely a debugging method! */
|
---|
[25635] | 1029 | private String tableToString(Hashtable<String, Hashtable<String, String>> table)
|
---|
[24753] | 1030 | {
|
---|
[24019] | 1031 | String str = "";
|
---|
[25635] | 1032 | Enumeration<String> keys = table.keys();
|
---|
[24753] | 1033 | while (keys.hasMoreElements())
|
---|
| 1034 | {
|
---|
[25635] | 1035 | String name = keys.nextElement();
|
---|
[24019] | 1036 | str += name + ", ";
|
---|
| 1037 | }
|
---|
| 1038 | return str;
|
---|
| 1039 | }
|
---|
[6301] | 1040 |
|
---|
[24753] | 1041 | /**
|
---|
| 1042 | * this goes through each URL and adds in a session id if needed-- its
|
---|
| 1043 | * needed if the browser doesn't accept cookies also escapes things if
|
---|
| 1044 | * needed
|
---|
| 1045 | */
|
---|
| 1046 | protected void encodeURLs(Node dataNode, HttpServletResponse response)
|
---|
| 1047 | {
|
---|
| 1048 | if (dataNode == null)
|
---|
| 1049 | {
|
---|
[24019] | 1050 | return;
|
---|
| 1051 | }
|
---|
[16515] | 1052 |
|
---|
[24753] | 1053 | Element data = null;
|
---|
[16515] | 1054 |
|
---|
[24019] | 1055 | short nodeType = dataNode.getNodeType();
|
---|
[24753] | 1056 | if (nodeType == Node.DOCUMENT_NODE)
|
---|
| 1057 | {
|
---|
| 1058 | Document docNode = (Document) dataNode;
|
---|
| 1059 | data = docNode.getDocumentElement();
|
---|
[24019] | 1060 | }
|
---|
[24753] | 1061 | else
|
---|
| 1062 | {
|
---|
| 1063 | data = (Element) dataNode;
|
---|
[24019] | 1064 | }
|
---|
[16515] | 1065 |
|
---|
[24753] | 1066 | if (data != null)
|
---|
| 1067 | {
|
---|
[19984] | 1068 |
|
---|
[24019] | 1069 | // get all the <a> elements
|
---|
| 1070 | NodeList hrefs = data.getElementsByTagName("a");
|
---|
| 1071 | // Instead of calculating each iteration...
|
---|
| 1072 | int hrefscount = hrefs.getLength();
|
---|
[23790] | 1073 |
|
---|
[24753] | 1074 | for (int i = 0; hrefs != null && i < hrefscount; i++)
|
---|
| 1075 | {
|
---|
| 1076 | Element a = (Element) hrefs.item(i);
|
---|
[24019] | 1077 | // ugly hack to get rid of : in the args - interferes with session handling
|
---|
| 1078 | String href = a.getAttribute("href");
|
---|
[24753] | 1079 | if (!href.equals(""))
|
---|
| 1080 | {
|
---|
| 1081 | if (href.indexOf("?") != -1)
|
---|
| 1082 | {
|
---|
[24019] | 1083 | String[] parts = StringUtils.split(href, "\\?", -1);
|
---|
| 1084 | if (parts.length == 1)
|
---|
| 1085 | {
|
---|
| 1086 | parts[0] = StringUtils.replace(parts[0], ":", "%3A");
|
---|
[24753] | 1087 | href = "?" + parts[0];
|
---|
[24019] | 1088 | }
|
---|
| 1089 | else
|
---|
| 1090 | {
|
---|
| 1091 | parts[1] = StringUtils.replace(parts[1], ":", "%3A");
|
---|
[24753] | 1092 | href = parts[0] + "?" + parts[1];
|
---|
[24019] | 1093 | }
|
---|
[24753] | 1094 |
|
---|
[24019] | 1095 | }
|
---|
| 1096 | a.setAttribute("href", response.encodeURL(href));
|
---|
| 1097 | }
|
---|
| 1098 | }
|
---|
[24753] | 1099 |
|
---|
[24019] | 1100 | // now find any submit bits - get all the <form> elements
|
---|
| 1101 | NodeList forms = data.getElementsByTagName("form");
|
---|
| 1102 | int formscount = forms.getLength();
|
---|
[24753] | 1103 | for (int i = 0; forms != null && i < formscount; i++)
|
---|
| 1104 | {
|
---|
| 1105 | Element form = (Element) forms.item(i);
|
---|
[24019] | 1106 | form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
|
---|
| 1107 | }
|
---|
| 1108 | // are these the only cases where URLs occur??
|
---|
| 1109 | // we should only do this for greenstone urls?
|
---|
[19984] | 1110 | }
|
---|
[24753] | 1111 |
|
---|
[19984] | 1112 | }
|
---|
[18223] | 1113 |
|
---|
[27617] | 1114 | protected String getFirstParam(String name, Map<String, String[]> map)
|
---|
| 1115 | {
|
---|
| 1116 | String[] val = map.get(name);
|
---|
| 1117 | if (val == null || val.length == 0)
|
---|
| 1118 | {
|
---|
| 1119 | return null;
|
---|
| 1120 | }
|
---|
| 1121 |
|
---|
| 1122 | return val[0];
|
---|
| 1123 | }
|
---|
| 1124 |
|
---|
[24753] | 1125 | synchronized protected int getNextUserId()
|
---|
| 1126 | {
|
---|
[24019] | 1127 | next_user_id++;
|
---|
| 1128 | return next_user_id;
|
---|
| 1129 | }
|
---|
[18223] | 1130 |
|
---|
[24753] | 1131 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
---|
| 1132 | {
|
---|
[27617] | 1133 | //Check if we need to process a file upload
|
---|
| 1134 | if (ServletFileUpload.isMultipartContent(request))
|
---|
| 1135 | {
|
---|
| 1136 | DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
|
---|
| 1137 |
|
---|
| 1138 | int sizeLimit = System.getProperties().containsKey("servlet.upload.filesize.limit") ? Integer.parseInt(System.getProperty("servlet.upload.filesize.limit")) : 100 * 1024 * 1024;
|
---|
| 1139 |
|
---|
| 1140 | File tempDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp");
|
---|
| 1141 | if (!tempDir.exists())
|
---|
| 1142 | {
|
---|
| 1143 | tempDir.mkdirs();
|
---|
| 1144 | }
|
---|
| 1145 |
|
---|
| 1146 | //We want all files to be stored on disk (hence the 0)
|
---|
| 1147 | fileItemFactory.setSizeThreshold(0);
|
---|
| 1148 | fileItemFactory.setRepository(tempDir);
|
---|
| 1149 |
|
---|
| 1150 | ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
|
---|
| 1151 | uploadHandler.setFileSizeMax(sizeLimit);
|
---|
| 1152 |
|
---|
| 1153 | HashMap<String, String[]> queryMap = new HashMap<String, String[]>();
|
---|
| 1154 | try
|
---|
| 1155 | {
|
---|
| 1156 | List items = uploadHandler.parseRequest(request);
|
---|
| 1157 | Iterator iter = items.iterator();
|
---|
| 1158 | while (iter.hasNext())
|
---|
| 1159 | {
|
---|
| 1160 | FileItem current = (FileItem) iter.next();
|
---|
| 1161 | if (current.isFormField())
|
---|
| 1162 | {
|
---|
| 1163 | queryMap.put(current.getFieldName(), new String[] { current.getString() });
|
---|
| 1164 | }
|
---|
| 1165 | else if (current.getName() != null && !current.getName().equals(""))
|
---|
| 1166 | {
|
---|
| 1167 | File file = new File(tempDir, current.getName());
|
---|
| 1168 | current.write(file);
|
---|
| 1169 | }
|
---|
| 1170 | }
|
---|
| 1171 | }
|
---|
| 1172 | catch (Exception e)
|
---|
| 1173 | {
|
---|
| 1174 | e.printStackTrace();
|
---|
| 1175 | }
|
---|
| 1176 |
|
---|
| 1177 | doGetOrPost(request, response, queryMap);
|
---|
| 1178 | }
|
---|
| 1179 | else
|
---|
| 1180 | {
|
---|
| 1181 | doGetOrPost(request, response, request.getParameterMap());
|
---|
| 1182 | }
|
---|
[24019] | 1183 | }
|
---|
[3309] | 1184 | }
|
---|