001    // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 
002    // The Molly framework is freely distributable under the terms of an
003    // MIT-style license. For details, see the molly pages web site at:
004    // http://www.mollypages.org/. Use, modify, have fun !
005    
006    package fc.web.servlet;
007    
008    import java.util.*;
009    import java.io.*;
010    import java.security.*;
011    import javax.servlet.*;
012    import javax.servlet.http.*;
013    
014    import fc.io.*;
015    import fc.util.*;
016    
017    /**
018    Misc utility methods for sessions and cookies.
019    
020    @author hursh jain
021    **/
022    public final class SessionUtil 
023    {
024    static final String TestCookieName = "eikooc";
025      
026    /**
027    Sets a test cookies. The user should be redirected to this or some other
028    page after calling this method and the presence of this cookie can be
029    checked via {@link hasTestCookie} from that page. The lifetime of the
030    test cookie is set to the browsers lifetime (will be lost when the
031    browser exits).
032    */
033    public static void setTestCookie(
034      HttpServletRequest req, HttpServletResponse res)
035      {
036      Cookie c = new Cookie(TestCookieName, "scotchAndsoda");
037      c.setMaxAge(-1);
038      res.addCookie(c);
039      }
040    
041    /**
042    Returns true if the browser accepts cookies. The {@link setTestCookie()}
043    method must have been invoked by some page prior to calling this method
044    AND the user must have been either redirected to that or some other page
045    AND this method must be invoked from that redirected page.
046    <p>
047    <b>Note:</b>
048    Test cookies are entirely self contained. They are meant to figure out if
049    a browser accepts cookies. Their presence or absence does not mean that
050    <b>other</b> cookies will not be sent by the browser. These other cookies
051    may point to a expired session in memory or database and a seperate check
052    for that should be made.
053    */
054    public static boolean hasTestCookie(
055      HttpServletRequest req, HttpServletResponse res)
056      {
057      Cookie[] cookies = req.getCookies();
058      if (cookies == null)
059        return false;
060    
061      for (int n = 0; n < cookies.length; n++) {
062        if (cookies[n].getName().equals(TestCookieName))
063          return true;
064        }
065    
066      return false;
067      }
068    
069    /**
070    Removes the test cookies if previously set. Normally, the
071    test cookie set by the {@link #setTestCookie} method is
072    automatically removed when the browser exists, but this
073    method allows removing it before such time.
074    */
075    public static void deleteTestCookie(
076      HttpServletRequest req, HttpServletResponse res)
077      {
078      Cookie[] cookies = req.getCookies();
079      if (cookies == null)
080        return;
081    
082      for (int n = 0; n < cookies.length; n++) 
083        {
084        if (cookies[n].getName().equals(TestCookieName))
085          {
086          cookies[n].setMaxAge(0);
087          res.addCookie(cookies[n]);
088          break;
089          }
090        }
091      }
092    
093    /**
094    Returns a new session identifier.
095    <pre>
096    See: cookies.lcs.mit.edu
097    See: www.across.si
098    
099    There are 2 issues with generating sessionid's. 
100    
101    1) uniqueness - 2 or more sessionid's should not end up being 
102       the same.
103    2) hard-to-guess - For example, sequential values like 
104       1, 2, 3 are unique but easy to guess and therefore easy
105       to session hijack.
106    
107    Our sessionid's have 2 parts:
108    a) a timestamp for guaranteed uniqueness  (easy to guess)
109    b) random data (hard to guess)
110    </pre>
111    */
112    public static String newSessionID() 
113      {
114      return UUIDUtil.newSessionID();
115      }
116    }