[open-ils-commits] r16612 - in trunk/Open-ILS: examples include/openils src/c-apps (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Mon Jun 7 09:52:31 EDT 2010


Author: scottmk
Date: 2010-06-07 09:52:29 -0400 (Mon, 07 Jun 2010)
New Revision: 16612

Modified:
   trunk/Open-ILS/examples/opensrf.xml.example
   trunk/Open-ILS/include/openils/oils_constants.h
   trunk/Open-ILS/src/c-apps/oils_auth.c
Log:
Added a new login type "persist", as a peer of "opac", "staff", and "temp".
It is intended for sessions that may stay open for days or weeks at a time
even in the absence of activity.  The default timeout interval is defined
as two weeks in opensrf.xml, and may be overridden by the org unit
setting "auth.persistent_login_interval".

Timeout resets work a little differently for persistent logins.  They
have no effect unless the session is within ten minutes of expiring.  When
they do take effect, they reset the timeout to ten minutes, rather than to
the full length of the original timeout.  That way we can avoid rudely
interrupting an active session without extending it excessively.

The ten minute reset interval for persistent timeouts is currently
hard-coded.  With some further work it could be made configurable.

The timeout resets for the older login types still work the way they
always have.

------------

In order to make it easier to specify long timeout intervals, the
auth server now accepts PostgreSQL-style interval strings, such as
"15 minutes" or "2 weeks".  Such strings work for any of the login
types, and they work either in opensrf.xml or in the org unit setting
values.

If the timeout setting (in either context) is all digits, then it will
be interpreted as an integral number of seconds, as it has been in the
past.  So existing settings will almost certainly continue to work
without change.

The exception -- an unlikely one -- is if the existing setting carries
a leading plus sign.  Under the old regime, a leading plus sign was
simply superfluous, and had no effect.  With the new version, a
leading plus sign means that the following number is to be treated as
a number of hours, rather than a number of seconds (just because
that's what PostgreSQL does with it).

Hence in the unlikely event that existing settings use a leading
plus sign, this change will make those timeouts 3600 times as long
as they should be.

If the timeout interval is expressed as anything other than a string
of all digits (possibly with leading and/or trailing white space), we
make a database call to get PostgreSQL to interpret it for us.  So the
convenience of using interval strings comes at the price of some
additional overhead.

--------------

Besides applying the changes to the C code, it will be necessary to
update the opensrf.xml file in order to define a default timeout
interval for the new login type.

M    Open-ILS/include/openils/oils_constants.h
M    Open-ILS/src/c-apps/oils_auth.c
M    Open-ILS/examples/opensrf.xml.example


Modified: trunk/Open-ILS/examples/opensrf.xml.example
===================================================================
--- trunk/Open-ILS/examples/opensrf.xml.example	2010-06-07 06:19:33 UTC (rev 16611)
+++ trunk/Open-ILS/examples/opensrf.xml.example	2010-06-07 13:52:29 UTC (rev 16612)
@@ -395,6 +395,7 @@
                         <opac>420</opac>
                         <staff>7200</staff>
                         <temp>300</temp>
+						<persist>2 weeks</persist>
                     </default_timeout>
                 </app_settings>
             </open-ils.auth>

Modified: trunk/Open-ILS/include/openils/oils_constants.h
===================================================================
--- trunk/Open-ILS/include/openils/oils_constants.h	2010-06-07 06:19:33 UTC (rev 16611)
+++ trunk/Open-ILS/include/openils/oils_constants.h	2010-06-07 13:52:29 UTC (rev 16612)
@@ -9,8 +9,8 @@
 #define OILS_ORG_SETTING_OPAC_TIMEOUT "auth.opac_timeout"
 #define OILS_ORG_SETTING_STAFF_TIMEOUT "auth.staff_timeout"
 #define OILS_ORG_SETTING_TEMP_TIMEOUT "auth.temp_timeout"
+#define OILS_ORG_SETTING_PERSIST_TIMEOUT "auth.persistent_login_interval"
 
-
 /* Events ------------------------------------------------------ */
 #define OILS_EVENT_SUCCESS "SUCCESS"
 #define OILS_EVENT_AUTH_FAILED "LOGIN_FAILED"

Modified: trunk/Open-ILS/src/c-apps/oils_auth.c
===================================================================
--- trunk/Open-ILS/src/c-apps/oils_auth.c	2010-06-07 06:19:33 UTC (rev 16611)
+++ trunk/Open-ILS/src/c-apps/oils_auth.c	2010-06-07 13:52:29 UTC (rev 16612)
@@ -14,7 +14,7 @@
 #define OILS_AUTH_OPAC "opac"
 #define OILS_AUTH_STAFF "staff"
 #define OILS_AUTH_TEMP "temp"
-#define OILS_AUTH_PERSISTENT "persistent"
+#define OILS_AUTH_PERSIST "persist"
 
 // Default time for extending a persistent session: ten minutes
 #define DEFAULT_RESET_INTERVAL 10 * 60
@@ -25,6 +25,7 @@
 static long _oilsAuthOPACTimeout = 0;
 static long _oilsAuthStaffTimeout = 0;
 static long _oilsAuthOverrideTimeout = 0;
+static long _oilsAuthPersistTimeout = 0;
 
 
 /**
@@ -177,6 +178,9 @@
 	} else if(!strcasecmp(type, OILS_AUTH_TEMP)) {
 		char* permissions[] = { "STAFF_LOGIN" };
 		perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
+	} else if(!strcasecmp(type, OILS_AUTH_PERSIST)) {
+		char* permissions[] = { "PERSISTENT_LOGIN" };
+		perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
 	}
 
 	if(perm) {
@@ -255,12 +259,23 @@
 }
 
 /**
-	Calculates the login timeout
-	1. If orgloc is 1 or greater and has a timeout specified as an
-	org unit setting, it is used
-	2. If orgloc is not valid, we check the org unit auth timeout
-	setting for the home org unit of the user logging in
-	3. If that setting is not defined, we use the configured defaults
+	@brief Determine the login timeout.
+	@param userObj Pointer to an object describing the user.
+	@param type Pointer to one of four possible character strings identifying the login type.
+	@param orgloc Org unit to use for settings lookups (negative or zero means unspecified)
+	@return The length of the timeout, in seconds.
+
+	The default timeout value comes from the configuration file, and depends on the
+	login type.
+
+	The default may be overridden by a corresponding org unit setting.  The @a orgloc
+	parameter says what org unit to use for the lookup.  If @a orgloc <= 0, or if the
+	lookup for @a orgloc yields no result, we look up the setting for the user's home org unit
+	instead (except that if it's the same as @a orgloc we don't bother repeating the lookup).
+
+	Whether defined in the config file or in an org unit setting, a timeout value may be
+	expressed as a raw number (i.e. all digits, possibly with leading and/or trailing white
+	space) or as an interval string to be translated into seconds by PostgreSQL.
 */
 static long oilsAuthGetTimeout( const jsonObject* userObj, const char* type, int orgloc ) {
 
@@ -270,59 +285,101 @@
 
 		value_obj = osrf_settings_host_value_object(
 			"/apps/open-ils.auth/app_settings/default_timeout/opac" );
-		_oilsAuthOPACTimeout = (long) jsonObjectGetNumber(value_obj);
+		_oilsAuthOPACTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj ));
 		jsonObjectFree(value_obj);
+		if( -1 == _oilsAuthOPACTimeout ) {
+			osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for OPAC logins" );
+			_oilsAuthOPACTimeout = 0;
+		}
 
 		value_obj = osrf_settings_host_value_object(
 			"/apps/open-ils.auth/app_settings/default_timeout/staff" );
-		_oilsAuthStaffTimeout = (long) jsonObjectGetNumber(value_obj);
+		_oilsAuthStaffTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj ));
 		jsonObjectFree(value_obj);
+		if( -1 == _oilsAuthStaffTimeout ) {
+			osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for staff logins" );
+			_oilsAuthStaffTimeout = 0;
+		}
 
 		value_obj = osrf_settings_host_value_object(
-				"/apps/open-ils.auth/app_settings/default_timeout/temp" );
-		_oilsAuthOverrideTimeout = (long) jsonObjectGetNumber(value_obj);
+			"/apps/open-ils.auth/app_settings/default_timeout/temp" );
+		_oilsAuthOverrideTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj ));
 		jsonObjectFree(value_obj);
+		if( -1 == _oilsAuthOverrideTimeout ) {
+			osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for temp logins" );
+			_oilsAuthOverrideTimeout = 0;
+		}
 
+		value_obj = osrf_settings_host_value_object(
+			"/apps/open-ils.auth/app_settings/default_timeout/persist" );
+		_oilsAuthPersistTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj ));
+		jsonObjectFree(value_obj);
+		if( -1 == _oilsAuthPersistTimeout ) {
+			osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for persist logins" );
+			_oilsAuthPersistTimeout = 0;
+		}
 
-		osrfLogInfo(OSRF_LOG_MARK,
-				"Set default auth timeouts: opac => %ld : staff => %ld : temp => %ld",
-				_oilsAuthOPACTimeout, _oilsAuthStaffTimeout, _oilsAuthOverrideTimeout );
+		osrfLogInfo(OSRF_LOG_MARK, "Set default auth timeouts: "
+			"opac => %ld : staff => %ld : temp => %ld : persist => %ld",
+			_oilsAuthOPACTimeout, _oilsAuthStaffTimeout,
+			_oilsAuthOverrideTimeout, _oilsAuthPersistTimeout );
 	}
 
-	char* setting = NULL;
-
 	int home_ou = (int) jsonObjectGetNumber( oilsFMGetObject( userObj, "home_ou" ));
 	if(orgloc < 1)
 		orgloc = home_ou;
 
-	if(!strcmp(type, OILS_AUTH_OPAC))
+	char* setting = NULL;
+	long default_timeout = 0;
+
+	if( !strcmp( type, OILS_AUTH_OPAC )) {
 		setting = OILS_ORG_SETTING_OPAC_TIMEOUT;
-	else if(!strcmp(type, OILS_AUTH_STAFF))
+		default_timeout = _oilsAuthOPACTimeout;
+	} else if( !strcmp( type, OILS_AUTH_STAFF )) {
 		setting = OILS_ORG_SETTING_STAFF_TIMEOUT;
-	else if(!strcmp(type, OILS_AUTH_TEMP))
+		default_timeout = _oilsAuthStaffTimeout;
+	} else if( !strcmp( type, OILS_AUTH_TEMP )) {
 		setting = OILS_ORG_SETTING_TEMP_TIMEOUT;
+		default_timeout = _oilsAuthOverrideTimeout;
+	} else if( !strcmp( type, OILS_AUTH_PERSIST )) {
+		setting = OILS_ORG_SETTING_PERSIST_TIMEOUT;
+		default_timeout = _oilsAuthPersistTimeout;
+	}
 
+	// Get the org unit setting, if there is one.
 	char* timeout = oilsUtilsFetchOrgSetting( orgloc, setting );
-
 	if(!timeout) {
 		if( orgloc != home_ou ) {
 			osrfLogDebug(OSRF_LOG_MARK, "Auth timeout not defined for org %d, "
-								"trying home_ou %d", orgloc, home_ou );
+				"trying home_ou %d", orgloc, home_ou );
 			timeout = oilsUtilsFetchOrgSetting( home_ou, setting );
 		}
-		if(!timeout) {
-			if( !strcmp(type, OILS_AUTH_STAFF ))
-				return _oilsAuthStaffTimeout;
-			else if( !strcmp( type, OILS_AUTH_TEMP ))
-				return _oilsAuthOverrideTimeout;
-			else
-				return _oilsAuthOPACTimeout;
+	}
+
+	if(!timeout)
+		return default_timeout;   // No override from org unit setting
+
+	// Translate the org unit setting to a number
+	long t;
+	if( !*timeout ) {
+		osrfLogWarning( OSRF_LOG_MARK,
+			"Timeout org unit setting is an empty string for %s login; using default",
+			timeout, type );
+		t = default_timeout;
+	} else {
+		// Treat timeout string as an interval, and convert it to seconds
+		t = oilsUtilsIntervalToSeconds( timeout );
+		if( -1 == t ) {
+			// Unable to convert; possibly an invalid interval string
+			osrfLogError( OSRF_LOG_MARK,
+				"Unable to convert timeout interval \"%s\" for %s login; using default",
+				timeout, type );
+			t = default_timeout;
 		}
 	}
 
-	long t = (long) atof(timeout);
 	free(timeout);
-	return t ;
+	return t;
 }
 
 /*
@@ -365,6 +422,19 @@
 	jsonObject* cacheObj = jsonParseFmt( "{\"authtime\": %ld}", timeout );
 	jsonObjectSetKey( cacheObj, "userobj", jsonObjectClone(userObj));
 
+	if( !strcmp( type, OILS_AUTH_PERSIST )) {
+		// Add entries for endtime and reset_interval, so that we can gracefully
+		// extend the session a bit if the user is active toward the end of the 
+		// timeout originally specified.
+		time_t endtime = time( NULL ) + timeout;
+		jsonObjectSetKey( cacheObj, "endtime", jsonNewNumberObject( (double) endtime ) );
+
+		// Reset interval is hard-coded for now, but if we ever want to make it
+		// configurable, this is the place to do it:
+		jsonObjectSetKey( cacheObj, "reset_interval",
+			jsonNewNumberObject( (double) DEFAULT_RESET_INTERVAL ));
+	}
+
 	osrfCachePutObject( authKey, cacheObj, (time_t) timeout );
 	jsonObjectFree(cacheObj);
 	osrfLogInternal(OSRF_LOG_MARK, "oilsAuthHandleLoginOK(): Placed user object into cache");



More information about the open-ils-commits mailing list