package org.crosswire.utils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.UUID; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.FileInputStream; import java.io.ObjectInputStream; import java.io.File; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Cookie; public class Sessions { static public long DEFAULT_SESSION_TIMEOUT = 1000 * 60 * 60 * 48; // 48 hour public static String persistRoot = System.getProperty("catalina.base") + "/sessions"; static Sessions systemSessions = new Sessions(); static public Sessions getInstance() { return systemSessions; } private void flushExpiredSessions() { File repo = new File(persistRoot); File sessions[] = repo.listFiles(); if (sessions != null) { for (File f : sessions) { if (f.getName().endsWith(".ser")) { long lastAccess = f.lastModified(); // we've been given an explicit TTL long ttl = DEFAULT_SESSION_TIMEOUT; if (f.getName().indexOf("_") > -1) { try { ttl = Long.parseLong(f.getName().substring(f.getName().indexOf("_")+1, f.getName().lastIndexOf("."))); } catch (Exception e) {} } if (System.currentTimeMillis() - lastAccess > ttl) { f.delete(); } } } } } public Map getSessionAttributes(String sessionHash) { if (sessionHash == null) return null; flushExpiredSessions(); Map session = loadSession(sessionHash); return session; } public void setSessionAttributes(String sessionHash, Mapattrs) { if (sessionHash == null || attrs == null) return; Map s = getSessionAttributes(sessionHash); if (s != null) { s.putAll(attrs); persistSession(sessionHash, s); } } public void setSessionAttribute(String sessionHash, String key, Object value) { if (sessionHash == null || key == null) return; Map s = getSessionAttributes(sessionHash); if (s != null) { s.put(key, value); persistSession(sessionHash, s); } } public Object getSessionAttribute(String sessionHash, String key) { if (sessionHash == null || key == null) return null; Map s = getSessionAttributes(sessionHash); return (s != null) ? s.get(key) : null; } public String createSession() { return createSession(-1); } public String createSession(long explicitTTL) { String sessionHash = UUID.randomUUID().toString(); if (explicitTTL > 0) sessionHash += "_" + Long.toString(explicitTTL); Map newSession = new ConcurrentHashMap(); persistSession(sessionHash, newSession); return sessionHash; } public void closeSession(String sessionHash) { if (sessionHash == null) return; File file = new File(persistRoot, sessionHash+".ser"); file.delete(); } private void persistSession(String sessionHash, Map session) { try { FileOutputStream fileOut = new FileOutputStream(persistRoot+"/"+sessionHash+".ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(session); out.close(); fileOut.close(); } catch(Exception e) { e.printStackTrace(); } } Map loadSession(String sessionHash) { if ("undefined".equals(sessionHash)) return null; Map session = null; File file = null; try { file = new File(persistRoot, sessionHash+".ser"); FileInputStream fileIn = new FileInputStream(file); ObjectInputStream in = new ObjectInputStream(fileIn); session = (Map) in.readObject(); in.close(); fileIn.close(); if (session != null) { file.setLastModified(System.currentTimeMillis()); } } catch(java.io.FileNotFoundException e) { System.out.println("Session file not found: " + file.getAbsolutePath()); } catch(Exception e) { e.printStackTrace(); } return session; } // TODO: Don't use this method. More complete and accurate impl in RightsAndRoles.getCurrentSession static public String getSessionHash(HttpServletRequest request) { String sessionHash = request.getParameter("sessionHash"); try { if (sessionHash != null) sessionHash = new String(sessionHash.getBytes("iso8859-1"), "UTF-8"); } catch (Exception e) {} if (sessionHash == null) { Cookie cookies[] = request.getCookies(); if (cookies != null) { for (Cookie c : cookies) { if ("ntvmrSession".equals(c.getName())) { sessionHash = c.getValue(); } } } } return sessionHash; } static public Map getSessionAttributes(HttpServletRequest request) { String sessionHash = getSessionHash(request); return Sessions.getInstance().getSessionAttributes(sessionHash); } static public long getSessionLongValue(HttpServletRequest request, String key) { long retVal = -1; try { Map s = getSessionAttributes(request); if (s != null) { Long l = (Long)s.get(key); if (l != null) retVal = l.longValue(); } } catch (Exception e) {} return retVal; } static public String getSessionStringValue(HttpServletRequest request, String key) { String retVal = null; try { Map s = getSessionAttributes(request); if (s != null) { retVal = (String)s.get(key); } } catch (Exception e) {} return retVal; } static public boolean hasRole(HttpServletRequest request, String role) { return hasRole(request, role, -1, null); } static public boolean hasRole(HttpServletRequest request, String role, int projectID) { return hasRole(request, role, projectID, null); } static public boolean hasRole(HttpServletRequest request, String role, int projectID, String userGroupName) { // TODO: VMR Impl, right now. Extract this out somewhere boolean retVal = false; long userID = Sessions.getSessionLongValue(request, "userID"); if (userID != -1) { try { String roleCheckURL = Utils.getSysConfig(request.getSession()).getProperty("VMRAPIBaseURL")+"/auth/hasrole/"; String params = "sessionHash=" + Sessions.getSessionHash(request) + "&role=" + java.net.URLEncoder.encode(role, "UTF-8"); if (projectID > -1) params += "&projectID=" + projectID; if (userGroupName != null) params += "&userGroupName=" + java.net.URLEncoder.encode(userGroupName, "UTF-8"); StringBuffer result = HTTPUtils.postURL(roleCheckURL, params); retVal = result.toString().trim().indexOf("hasRole=\"true\"") > -1; } catch (Exception e) {} } return retVal; } }