1515# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717#
18- # $Id: cgi_client.py,v 1.134 2002-07-09 04:19:09 richard Exp $
18+ # $Id: cgi_client.py,v 1.135 2002-07-10 00:22:34 richard Exp $
1919
2020__doc__ = """
2121WWW request handler (also used in the stand-alone server).
@@ -112,7 +112,7 @@ def header(self, headers=None):
112112}
113113
114114function help_window(helpurl, width, height) {
115- HelpWin = window.open('%(base)s%(instance_path_name)s/' + helpurl, 'HelpWindow ', 'scrollbars=yes,resizable=yes,toolbar=no,height='+height+',width='+width);
115+ HelpWin = window.open('%(base)s%(instance_path_name)s/' + helpurl, 'RoundupHelpWindow ', 'scrollbars=yes,resizable=yes,toolbar=no,height='+height+',width='+width);
116116}
117117
118118</script>
@@ -431,21 +431,6 @@ def index(self):
431431 def searchnode (self ):
432432 columns , filter , group , sort , filterspec , pagesize = \
433433 self ._get_customisation_info ()
434- ## show_nodes = 1
435- ## if len(self.form.keys()) == 0:
436- ## # get the default search filters from instance_config
437- ## if hasattr(self.instance, 'SEARCH_FILTERS'):
438- ## for f in self.instance.SEARCH_FILTERS:
439- ## spec = getattr(self.instance, f)
440- ## if spec['CLASS'] == self.classname:
441- ## filter = spec['FILTER']
442- ##
443- ## show_nodes = 0
444- ## show_customization = 1
445- ## return self.list(columns=columns, filter=filter, group=group,
446- ## sort=sort, filterspec=filterspec,
447- ## show_customization=show_customization, show_nodes=show_nodes,
448- ## pagesize=pagesize)
449434 cn = self .classname
450435 self .pagehead (_ ('%(instancename)s: Index of %(classname)s' )% {
451436 'classname' : cn , 'instancename' : self .instance .INSTANCE_NAME })
@@ -665,7 +650,8 @@ def shownode(self, message=None, num_re=re.compile('^\d+$')):
665650 id = self .nodeid
666651 if cl .getkey ():
667652 id = cl .get (id , cl .getkey ())
668- self .pagehead ('%s: %s %s' % (self .classname .capitalize (), id , xtra ), message )
653+ self .pagehead ('%s: %s %s' % (self .classname .capitalize (), id , xtra ),
654+ message )
669655
670656 nodeid = self .nodeid
671657
@@ -1111,6 +1097,8 @@ def login_action(self, message=None):
11111097 self .login (message = _ ('Username required' ))
11121098 return 0
11131099 self .user = self .form ['__login_name' ].value
1100+ # re-open the database for real, using the user
1101+ self .opendb (self .user )
11141102 if self .form .has_key ('__login_password' ):
11151103 password = self .form ['__login_password' ].value
11161104 else :
@@ -1144,7 +1132,7 @@ def newuser_action(self, message=None):
11441132 return 1 on successful login
11451133 '''
11461134 # re-open the database as "admin"
1147- self .db = self . instance . open ('admin' )
1135+ self .opendb ('admin' )
11481136
11491137 # TODO: pre-check the required fields and username key property
11501138 cl = self .db .user
@@ -1156,22 +1144,42 @@ def newuser_action(self, message=None):
11561144 self .login (message , action = action )
11571145 return 0
11581146 self .user = cl .get (uid , 'username' )
1147+ # re-open the database for real, using the user
1148+ self .opendb (self .user )
11591149 password = cl .get (uid , 'password' )
11601150 self .set_cookie (self .user , self .form ['password' ].value )
11611151 return 1
11621152
11631153 def set_cookie (self , user , password ):
1164- # construct the cookie
1165- user = binascii .b2a_base64 ('%s:%s' % (user , password )).strip ()
1166- if user [- 1 ] == '=' :
1167- if user [- 2 ] == '=' :
1168- user = user [:- 2 ]
1154+ # TODO generate a much, much stronger session key ;)
1155+ session = binascii .b2a_base64 (repr (time .time ())).strip ()
1156+
1157+ # clean up the base64
1158+ if session [- 1 ] == '=' :
1159+ if session [- 2 ] == '=' :
1160+ session = session [:- 2 ]
11691161 else :
1170- user = user [:- 1 ]
1162+ session = session [:- 1 ]
1163+
1164+ print 'session set to' , `session`
1165+
1166+ # insert the session in the sessiondb
1167+ self .db .getclass ('__sessions' ).create (sessid = session , user = user ,
1168+ last_use = date .Date ())
1169+
1170+ # and commit immediately
1171+ self .db .commit ()
1172+
1173+ # expire us in a long, long time
1174+ # TODO: hrm, how long should this be, and how many sessions can one
1175+ # user have?
11711176 expire = Cookie ._getdate (86400 * 365 )
1172- path = '/' .join ((self .env ['SCRIPT_NAME' ], self .env ['INSTANCE_NAME' ]))
1173- self .header ({'Set-Cookie' : 'roundup_user=%s; expires=%s; Path=%s;' % (
1174- user , expire , path )})
1177+
1178+ # generate the cookie path - make sure it has a trailing '/'
1179+ path = '/' .join ((self .env ['SCRIPT_NAME' ], self .env ['INSTANCE_NAME' ],
1180+ '' ))
1181+ self .header ({'Set-Cookie' : 'roundup_user=%s; expires=%s; Path=%s;' % (
1182+ session , expire , path )})
11751183
11761184 def make_user_anonymous (self ):
11771185 # make us anonymous if we can
@@ -1185,48 +1193,74 @@ def logout(self, message=None):
11851193 self .make_user_anonymous ()
11861194 # construct the logout cookie
11871195 now = Cookie ._getdate ()
1188- path = '/' .join ((self .env ['SCRIPT_NAME' ], self .env ['INSTANCE_NAME' ]))
1196+ path = '/' .join ((self .env ['SCRIPT_NAME' ], self .env ['INSTANCE_NAME' ],
1197+ '' ))
11891198 self .header ({'Set-Cookie' :
11901199 'roundup_user=deleted; Max-Age=0; expires=%s; Path=%s;' % (now ,
11911200 path )})
11921201 self .login ()
11931202
1203+ def opendb (self , user ):
1204+ ''' Open the database - but include the definition of the sessions db.
1205+ '''
1206+ # open the db
1207+ self .db = self .instance .open (user )
1208+
1209+ # make sure we have the session Class
1210+ try :
1211+ sessions = self .db .getclass ('__sessions' )
1212+ except :
1213+ # add the sessions Class
1214+ sessions = hyperdb .Class (self .db , '__sessions' ,
1215+ sessid = hyperdb .String (), user = hyperdb .String (),
1216+ last_use = hyperdb .Date ())
1217+ sessions .setkey ('sessid' )
1218+
11941219 def main (self ):
11951220 '''Wrap the database accesses so we can close the database cleanly
11961221 '''
11971222 # determine the uid to use
1198- self .db = self .instance .open ('admin' )
1223+ self .opendb ('admin' )
1224+
1225+ # make sure we have the session Class
1226+ sessions = self .db .getclass ('__sessions' )
1227+
1228+ # age sessions, remove when they haven't been used for a week
1229+ # TODO: this doesn't need to be done every access
1230+ week = date .Interval ('7d' )
1231+ now = date .Date ()
1232+ for sessid in sessions .list ():
1233+ interval = now - sessions .get (sessid , 'last_use' )
1234+ if interval > week :
1235+ sessions .destroy (sessid )
1236+
1237+ # look up the user session cookie
11991238 cookie = Cookie .Cookie (self .env .get ('HTTP_COOKIE' , '' ))
12001239 user = 'anonymous'
12011240 if (cookie .has_key ('roundup_user' ) and
12021241 cookie ['roundup_user' ].value != 'deleted' ):
1203- cookie = cookie ['roundup_user' ].value
1204- if len (cookie )% 4 :
1205- cookie = cookie + '=' * (4 - len (cookie )% 4 )
1206- try :
1207- user , password = binascii .a2b_base64 (cookie ).split (':' )
1208- except (TypeError , binascii .Error , binascii .Incomplete ):
1209- # damaged cookie!
1210- user , password = 'anonymous' , ''
1242+ print cookie
1243+
1244+ # get the session key from the cookie
1245+ session = cookie ['roundup_user' ].value
1246+ print 'session is' , `session`
12111247
1212- # make sure the user exists
1248+ # get the user from the session
12131249 try :
1214- uid = self .db .user .lookup (user )
1215- # now validate the password
1216- if password != self .db .user .get (uid , 'password' ):
1217- user = 'anonymous'
1250+ sessid = sessions .lookup (session )
12181251 except KeyError :
12191252 user = 'anonymous'
1253+ else :
1254+ sessions .set (sessid , last_use = date .Date ())
1255+ self .db .commit ()
1256+ user = sessions .get (sessid , 'user' )
12201257
12211258 # make sure the anonymous user is valid if we're using it
12221259 if user == 'anonymous' :
12231260 self .make_user_anonymous ()
12241261 else :
12251262 self .user = user
12261263
1227- # re-open the database for real, using the user
1228- self .db = self .instance .open (self .user )
1229-
12301264 # now figure which function to call
12311265 path = self .split_path
12321266
@@ -1279,6 +1313,9 @@ def main(self):
12791313 self .login (action = action )
12801314 return
12811315
1316+ # re-open the database for real, using the user
1317+ self .opendb (self .user )
1318+
12821319 # just a regular action
12831320 self .do_action (action )
12841321
@@ -1454,6 +1491,11 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
14541491
14551492#
14561493# $Log: not supported by cvs2svn $
1494+ # Revision 1.134 2002/07/09 04:19:09 richard
1495+ # Added reindex command to roundup-admin.
1496+ # Fixed reindex on first access.
1497+ # Also fixed reindexing of entries that change.
1498+ #
14571499# Revision 1.133 2002/07/08 15:32:05 gmcm
14581500# Pagination of index pages.
14591501# New search form.
0 commit comments