added global UI properties, cookie-reading APIs to CookieControl, moved

HttpVeniceUISession initialization into a script file (session_init.js)
This commit is contained in:
Eric J. Bowersox 2002-05-12 08:53:28 +00:00
parent 128c33cd9b
commit ffc862426a
12 changed files with 425 additions and 91 deletions

View File

@ -57,6 +57,19 @@
</uri-paths>
<!-- Properties which are "read-only" from the point of view of the application. -->
<properties>
<!-- The script which is run to initialize the Web session. -->
<property name="session.init">session_init.js</property>
<!-- The name of the persistent cookie used to automatically log users in. -->
<property name="login.cookie">VeniceAuth</property>
<!-- The maximum age of the persistent login cookie. -->
<property name="login.cookie.age">31536000</property> <!-- one year -->
</properties>
<!-- Settings related to the outer frame. -->
<frame>
<!-- The name of the JSP page that implements the outer frame. -->

View File

@ -10,7 +10,7 @@
//
// The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
// for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
// Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
// Copyright (C) 2001-2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
//
// Contributor(s):
@ -96,8 +96,9 @@ else if (op=="login")
if (dlg.getValue("saveme").booleanValue())
{ // If the user wants a cookie, give it to them!
cctl = vlib.queryCookieControl(rinput);
cctl.savePersistentCookie(CookieControl.LOGIN_COOKIE,user.getAuthenticationToken(),
CookieControl.LOGIN_COOKIE_AGE);
cctl.savePersistentCookie(rinput.getConfigProperty("login.cookie"),user.getAuthenticationToken(),
vlib.toInteger(rinput.getConfigProperty("login.cookie.age")));
} // end if
// Clear the left menus (to force recomputation) and bounce us back to whereever we were

View File

@ -10,7 +10,7 @@
//
// The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
// for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
// Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
// Copyright (C) 2001-2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
//
// Contributor(s):
@ -31,7 +31,7 @@ if (user.isLoggedIn())
{ // user is logged in - we want to log out
// TODO: only remove the login cookie if it was actually set!
cctl = vlib.queryCookieControl(rinput);
cctl.deleteCookie(CookieControl.LOGIN_COOKIE); // remove the login cookie
cctl.deleteCookie(rinput.getConfigProperty("login.cookie")); // remove the login cookie
sctl = vlib.querySessionControl(rinput);
sctl.endSession();

50
scripts/session_init.js Normal file
View File

@ -0,0 +1,50 @@
// The contents of this file are subject to the Mozilla Public License Version 1.1
// (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
// WARRANTY OF ANY KIND, either express or implied. See the License for the specific
// language governing rights and limitations under the License.
//
// The Original Code is the Venice Web Communities System.
//
// The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
// for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
// Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
//
// Contributor(s):
importPackage(Packages.com.silverwrist.venice.core);
importPackage(Packages.com.silverwrist.venice.except);
importPackage(Packages.com.silverwrist.venice.ui);
importPackage(Packages.com.silverwrist.venice.ui.helpers);
// Get the request and the session.
rinput = bsf.lookupBean("request");
sess = vlib.castVeniceUISession(bsf.lookupBean("session"));
// Get the login cookie name and the CookieControl service.
cookie_name = rinput.getConfigProperty("login.cookie");
cctl = vlib.queryCookieControl(rinput);
if (cctl.isCookiePresent(cookie_name))
{ // get the login cookie value and try to use it to log in
logger.debug("cookie " + cookie_name + " found");
logged_in = false;
try
{ // attempt to log the user in with the cookie
logged_in = sess.user.authenticateWithToken(cctl.getCookie(cookie_name));
} // end try
catch (e)
{ // login failed
logger.error("caught " + vlib.exceptionType(e) + ": " + e.message);
logged_in = false;
} // end catch
if (!logged_in) // not logged in - delete the cookie
cctl.deleteCookie(cookie_name);
} // end if
else
logger.debug("cookie " + cookie_name + " not found");

View File

@ -360,4 +360,8 @@ public interface RequestInput extends ServiceProvider
public abstract void registerCleanup(AutoCleanup ac);
public abstract String getConfigProperty(String name);
public abstract String getConfigProperty(String name, String default_val);
} // end interface RequestInput

View File

@ -17,8 +17,9 @@
*/
package com.silverwrist.venice.ui;
import java.util.*;
import com.silverwrist.venice.core.*;
import java.util.Enumeration;
import javax.servlet.ServletException;
import com.silverwrist.venice.core.UserContext;
public interface VeniceUISession
{
@ -46,6 +47,6 @@ public interface VeniceUISession
public abstract void setUser(UserContext user);
public abstract void preprocess(RequestInput ri);
public abstract void preprocess(RequestInput ri) throws ServletException;
} // end class VeniceUISession

View File

@ -63,6 +63,7 @@ public class RootConfig implements LinkTypes, ColorSelectors
private String external_static_path; // the external static files path
private String format_path; // the JSP formatter path
private String blank_photo_path; // the "photo not available" path
private Properties properties; // the property list
private String frame_jsp_name; // the name of the frame JSP
private String site_title; // the title for the site
private File stylesheet; // the stylesheet file reference
@ -196,6 +197,44 @@ public class RootConfig implements LinkTypes, ColorSelectors
if (sect1_h.hasAttribute("fixup"))
blank_photo_path = image_path + blank_photo_path;
// Load the default properties from the resources.
Properties defprops = new Properties();
try
{ // load the properties from the resource
defprops.load(getClass().getResourceAsStream("default-config.properties"));
} // end try
catch (IOException e)
{ // whoops!
throw new ConfigException("unable to load default application properties");
} // end catch
properties = new Properties(defprops); // create the actual properties
// Get the <properties/> section.
sect = loader.configGetSubSection(root_h,"properties");
// Loop through the section to find <property/> tags and add them to the property list.
NodeList nl;
int i;
if (sect!=null)
{ // get the child nodes
nl = sect.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // see if the node is a property value
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && n.getNodeName().equals("property"))
{ // add the property value to the map
sect1 = (Element)n;
properties.setProperty(loader.configGetAttribute(sect1,"name"),loader.configGetText(sect1));
} // end if
} // end for (all child nodes of <properties/>)
} // end if (<properties/> section exists)
// Get the <frame/> section.
sect = loader.configGetSubSection(root_h,"frame");
sect_h = new DOMElementHelper(sect);
@ -336,8 +375,6 @@ public class RootConfig implements LinkTypes, ColorSelectors
// Load the stock font sizes.
sect1 = sect_h.getSubElement("font-sizes");
HashMap tmap;
NodeList nl;
int i;
if (sect1!=null)
{ // scan through this subsection to find the stock font sizes
tmap = new HashMap();
@ -774,6 +811,18 @@ public class RootConfig implements LinkTypes, ColorSelectors
} // end getBlankPhoto
public final String getProperty(String name)
{
return properties.getProperty(name);
} // end getProperty
public final String getProperty(String name, String default_val)
{
return properties.getProperty(name,default_val);
} // end getProperty
public final CommunityMenu getCommunityMenu(CommunityContext comm)
{
return comm_menu_fact.createMenu(comm);
@ -804,7 +853,7 @@ public class RootConfig implements LinkTypes, ColorSelectors
*/
static
{
{ // create the link types
HashMap m = new HashMap();
m.put("absolute",new Integer(ABSOLUTE));
m.put("servlet",new Integer(SERVLET));

View File

@ -0,0 +1,20 @@
# The contents of this file are subject to the Mozilla Public License Version 1.1
# (the "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
#
# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
# language governing rights and limitations under the License.
#
# The Original Code is the Venice Web Communities System.
#
# The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
# Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
#
# Contributor(s):
# -------------------------------------------------------------------------------------
# Default values for the properties that are loaded from the ui-config.xml <properties/> section.
session.init=session_init.js
login.cookie=VeniceAuth
login.cookie.age=31536000

View File

@ -17,15 +17,60 @@
*/
package com.silverwrist.venice.ui.helpers;
import java.util.Set;
public interface CookieControl
{
public static final String LOGIN_COOKIE = "VeniceAuth";
public static final int LOGIN_COOKIE_AGE = 60*60*24*365; // one year
/**
* Tests for the presence of a particular cookie.
*
* @param name Name of the cookie to test for existence.
* @return <CODE>true</CODE> if a cookie by this name is present, <CODE>false</CODE> if not.
*/
public abstract boolean isCookiePresent(String name);
/**
* Returns the value of a particular request cookie.
*
* @param name Name of the cookie to retrieve the value of.
* @return The value of that cookie, or <CODE>null</CODE> if the cookie is not present.
*/
public abstract String getCookie(String name);
/**
* Returns a set containing all the cookie names associated with this request.
*
* @return See above.
*/
public abstract Set getCookieNames();
/**
* Adds a new persistent cookie to the application. The cookie will be stored by the
* browser's persistent storage facility.<P>
* Cookies should be used <EM>sparingly</EM>, to avoid possible privacy concerns.
*
* @param name Name of the cookie to be set.
* @param value Value of the cookie to be set.
* @param max_age The maximum lifespan of the persistent cookie, in seconds.
*/
public abstract void savePersistentCookie(String name, String value, int max_age);
/**
* Adds a new temporary cookie to the application. The cookie will be stored in the
* browser's memory only, and will disappear when the browser is closed.
* Cookies should be used <EM>sparingly</EM>, to avoid possible privacy concerns.
*
* @param name Name of the cookie to be set.
* @param value Value of the cookie to be set.
*/
public abstract void saveTemporaryCookie(String name, String value);
/**
* Deletes a cookie (either persistent or temporary) from the application. The cookie
* will be erased from the browser.
*
* @param name Name of the cookie to remove.
*/
public abstract void deleteCookie(String name);
} // end interface CookieControl

View File

@ -22,6 +22,7 @@ import java.util.*;
import org.w3c.dom.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.ui.VeniceUISession;
import com.silverwrist.venice.ui.helpers.CookieControl;
import com.silverwrist.venice.ui.helpers.HTMLRendering;
import com.silverwrist.venice.ui.helpers.SessionControl;
@ -128,6 +129,14 @@ public class ScriptLibrary
} // end castUserSideBoxDescriptor
public final VeniceUISession castVeniceUISession(Object o)
{
if (o instanceof VeniceUISession)
return (VeniceUISession)o;
throw new ClassCastException("ScriptLibrary.castVeniceUISession: invalid cast");
} // end castVeniceUISession
public final boolean[] createBooleanArray(int len)
{
return new boolean[len];
@ -184,6 +193,8 @@ public class ScriptLibrary
public final String exceptionType(Object o) throws ScriptExit
{
if (o==null)
return null;
if (o instanceof ScriptExit)
throw (ScriptExit)o; // rethrow ScriptExit exceptions
if (o instanceof Throwable)
@ -244,6 +255,15 @@ public class ScriptLibrary
} // end toInteger
public final String typeOf(Object o)
{
if (o==null)
return null;
else
return o.getClass().getName();
} // end typeOf
public final boolean validVeniceID(String s)
{
return IDUtils.isValidVeniceID(s);

View File

@ -17,6 +17,7 @@
*/
package com.silverwrist.venice.ui.servlet;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
@ -24,7 +25,8 @@ import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.helpers.CookieControl;
import com.silverwrist.venice.ui.helpers.*;
import com.silverwrist.venice.ui.script.*;
class HttpVeniceUISession implements VeniceUISession
{
@ -42,9 +44,9 @@ class HttpVeniceUISession implements VeniceUISession
*--------------------------------------------------------------------------------
*/
private HttpSession session;
private UserContext user;
private Cookie venice_cookie = null;
private HttpSession session; // HTTP session value
private UserContext user; // user context associated with this session
private boolean new_session = true; // is this a new session?
/*--------------------------------------------------------------------------------
* Constructor
@ -59,15 +61,6 @@ class HttpVeniceUISession implements VeniceUISession
{ // tell the engine to create us a user context
user = engine.createUserContext(request.getRemoteAddr());
// Did the user send a Venice authentication cookie? If so, try to use it.
Cookie[] cookies = request.getCookies();
for (int i=0; (venice_cookie==null) && (i<cookies.length); i++)
{ // look for a Venice authentication cookie
if (CookieControl.LOGIN_COOKIE.equals(cookies[i].getName()))
venice_cookie = cookies[i];
} // end for
} // end try
catch (DataException e)
{ // context creation failed - remap the exception
@ -165,28 +158,47 @@ class HttpVeniceUISession implements VeniceUISession
} // end setUser
public void preprocess(RequestInput ri)
public void preprocess(RequestInput ri) throws ServletException
{
if (venice_cookie!=null)
{ // try to log in with the cookie
try
{ // attempt authentication
if (!(user.authenticateWithToken(venice_cookie.getValue())))
{ // delete bogus cookie if it didn't work
CookieControl cctl = (CookieControl)(ri.queryService(CookieControl.class));
cctl.deleteCookie(CookieControl.LOGIN_COOKIE);
if (new_session)
{ // new session - we need to run the init script
String script_name = ri.getConfigProperty("session.init");
ScriptSupport ssup = (ScriptSupport)(ri.queryService(ScriptSupport.class));
String script_file = ssup.getScriptName(script_name);
String logger_name = ssup.getScriptLoggerName(script_name);
if (logger.isDebugEnabled())
logger.debug("EXECUTING " + script_file);
} // end if
// get the script manager and execute it!
ScriptManager smgr = (ScriptManager)(ri.queryService(ScriptManager.class));
smgr.pushContext();
try
{ // add the session to the bound variables
smgr.register("session",this);
try
{ // execute the script!
smgr.exec(new File(script_file),logger_name,new ScriptReturn());
} // end try
catch (DataException de)
{ // it didn't work...
CookieControl cctl = (CookieControl)(ri.queryService(CookieControl.class));
cctl.deleteCookie(CookieControl.LOGIN_COOKIE);
catch (ScriptingException e)
{ // there's a script exception here...
logger.error("Session init failed: " + e.getMessage(),e);
throw new ServletException("Session init failed: " + e.getMessage(),e);
} // end catch
catch (ThrowableContent tc)
{ // ignore this
logger.warn("session init script threw a ThrowableContent of type " + tc.getClass().getName());
} // end catch
venice_cookie = null;
} // end try
finally
{ // pop the context before we go
smgr.popContext();
new_session = false;
} // end finally
} // end if

View File

@ -540,43 +540,6 @@ public class RequestImpl implements RequestInput
} // end if
// Create the UI session.
session = factory.createSession(ctxt,request,response,engine,config);
session.preprocess(this);
if (!(session instanceof NullSession))
{ // read the user's preferred locale
try
{ // get the user default locale
my_locale = session.getUser().getLocale();
} // end try
catch (DataException de)
{ // locale problems...
my_locale = Locale.getDefault();
} // end catch
// read the user's preferred time zone
try
{ // get the user default timezone
my_timezone = session.getUser().getTimeZone();
} // end try
catch (DataException de)
{ // time zone problems...
my_timezone = TimeZone.getDefault();
} // end catch
} // end if
else
{ // just default locale/timezone
my_locale = Locale.getDefault();
my_timezone = TimeZone.getDefault();
} // end else
// Come up with a "first guess" at the location.
StringBuffer loc_buf = new StringBuffer(request.getServletPath());
if (loc_buf.charAt(0)=='/')
@ -608,6 +571,43 @@ public class RequestImpl implements RequestInput
} // end catch
// Default the locale and time zone temporarily while we initialize the session.
my_locale = Locale.getDefault();
my_timezone = TimeZone.getDefault();
// Create the UI session. We do this only after the script engine has been initialized
// because HttpVeniceUISession now calls the script engine to launch session_init.js.
session = factory.createSession(ctxt,request,response,engine,config);
session.preprocess(this);
if (!(session instanceof NullSession))
{ // read the user's preferred locale
try
{ // get the user default locale
my_locale = session.getUser().getLocale();
} // end try
catch (DataException de)
{ // locale problems...
my_locale = Locale.getDefault();
} // end catch
// read the user's preferred time zone
try
{ // get the user default timezone
my_timezone = session.getUser().getTimeZone();
} // end try
catch (DataException de)
{ // time zone problems...
my_timezone = TimeZone.getDefault();
} // end catch
} // end if
// else leave the locale and time zone where they are
} // end constructor
/*--------------------------------------------------------------------------------
@ -788,7 +788,7 @@ public class RequestImpl implements RequestInput
if (klass==CookieControl.class)
{ // create cookie control and return it
if (cookie_control==null)
cookie_control = new CookieControlImpl(this);
cookie_control = new CookieControlImpl(request);
return cookie_control;
} // end if
@ -1472,6 +1472,18 @@ public class RequestImpl implements RequestInput
} // end registerCleanup
public String getConfigProperty(String name)
{
return config.getProperty(name);
} // end getConfigProperty
public String getConfigProperty(String name, String default_val)
{
return config.getProperty(name,default_val);
} // end getConfigProperty
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
@ -1707,22 +1719,30 @@ class SessionControlImpl implements SessionControl
class CookieControlImpl implements CookieControl
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(CookieControlImpl.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private RequestImpl req; // request we're tied to
private ArrayList new_cookies = null; // cookies to be added to the response
private HttpServletRequest httpreq; // HTTP request object
private HashMap old_cookies = null; // cookies from the request
private HashMap new_cookies = null; // cookies to be added to the response
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
CookieControlImpl(RequestImpl req)
CookieControlImpl(HttpServletRequest httpreq)
{
this.req = req;
this.httpreq = httpreq;
} // end constructor
@ -1731,11 +1751,36 @@ class CookieControlImpl implements CookieControl
*--------------------------------------------------------------------------------
*/
private final void loadCookies()
{
if (old_cookies==null)
{ // load the cookies into a HashMap
old_cookies = new HashMap();
Cookie[] raw_list = httpreq.getCookies();
for (int i=0; i<raw_list.length; i++)
{ // save off the cookies
Cookie tmp = raw_list[i];
old_cookies.put(tmp.getName(),tmp);
} // end for
if (logger.isDebugEnabled())
logger.debug("loadCookies(): " + old_cookies.size() + " cookie(s) loaded");
} // end if
} // end loadCookies
/**
* Saves a cookie so that it will be added to the response.
*
* @param cookie Cookie to be added to the response later.
*/
private final void putCookie(Cookie cookie)
{
if (new_cookies==null)
new_cookies = new ArrayList();
new_cookies.add(cookie);
new_cookies = new HashMap();
new_cookies.put(cookie.getName(),cookie);
} // end putCookie
@ -1744,29 +1789,94 @@ class CookieControlImpl implements CookieControl
*--------------------------------------------------------------------------------
*/
/**
* Tests for the presence of a particular cookie.
*
* @param name Name of the cookie to test for existence.
* @return <CODE>true</CODE> if a cookie by this name is present, <CODE>false</CODE> if not.
*/
public boolean isCookiePresent(String name)
{
loadCookies();
return old_cookies.containsKey(name);
} // end isCookiePresent
/**
* Returns the value of a particular request cookie.
*
* @param name Name of the cookie to retrieve the value of.
* @return The value of that cookie, or <CODE>null</CODE> if the cookie is not present.
*/
public String getCookie(String name)
{
loadCookies();
Cookie tmp = (Cookie)(old_cookies.get(name));
return ((tmp==null) ? null : tmp.getValue());
} // end getCookie
/**
* Returns a set containing all the cookie names associated with this request.
*
* @return See above.
*/
public Set getCookieNames()
{
loadCookies();
if (old_cookies.isEmpty())
return Collections.EMPTY_SET;
else
return Collections.unmodifiableSet(old_cookies.keySet());
} // end getCookieNames
/**
* Adds a new persistent cookie to the application. The cookie will be stored by the
* browser's persistent storage facility.<P>
* Cookies should be used <EM>sparingly</EM>, to avoid possible privacy concerns.
*
* @param name Name of the cookie to be set.
* @param value Value of the cookie to be set.
* @param max_age The maximum lifespan of the persistent cookie, in seconds.
*/
public void savePersistentCookie(String name, String value, int max_age)
{
Cookie c = new Cookie(name,value);
c.setMaxAge(Math.max(max_age,1));
c.setPath(req.getContextPath());
c.setPath(httpreq.getContextPath());
putCookie(c);
} // end savePersistentCookie
/**
* Adds a new temporary cookie to the application. The cookie will be stored in the
* browser's memory only, and will disappear when the browser is closed.
* Cookies should be used <EM>sparingly</EM>, to avoid possible privacy concerns.
*
* @param name Name of the cookie to be set.
* @param value Value of the cookie to be set.
*/
public void saveTemporaryCookie(String name, String value)
{
Cookie c = new Cookie(name,value);
c.setMaxAge(-1);
c.setPath(req.getContextPath());
c.setPath(httpreq.getContextPath());
putCookie(c);
} // end saveTemporaryCookie
/**
* Deletes a cookie (either persistent or temporary) from the application. The cookie
* will be erased from the browser.
*
* @param name Name of the cookie to remove.
*/
public void deleteCookie(String name)
{
Cookie c = new Cookie(name,"");
c.setMaxAge(0);
c.setPath(req.getContextPath());
c.setPath(httpreq.getContextPath());
putCookie(c);
} // end deleteCookie
@ -1776,13 +1886,22 @@ class CookieControlImpl implements CookieControl
*--------------------------------------------------------------------------------
*/
/**
* Takes all cookies that have been set on the current request and writes them to the
* HTTP output.
*
* @param response HTTP response to receive all the cookies.
*/
final void flushCookies(HttpServletResponse response)
{
if (new_cookies==null)
return; // no-op
if (logger.isDebugEnabled())
logger.debug("flushCookies(): " + new_cookies.size() + " cookie(s) to output");
// loop over the cookies and add them to the response
Iterator it = new_cookies.iterator();
Iterator it = new_cookies.values().iterator();
while (it.hasNext())
{ // add cookies to the response
Cookie c = (Cookie)(it.next());