diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
index 8d425923416ef1e55e91e3c013e09a67aabe635d..86c1c83a3af78ef7d1ce05f36e911933688c34a8 100644 (file)
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
-# $Id: client.py,v 1.102 2003-03-07 21:51:31 richard Exp $
+# $Id: client.py,v 1.110 2003-03-26 03:35:00 richard Exp $
__doc__ = """
WWW request handler (also used in the stand-alone server).
class NotModified(HTTPException):
pass
+# set to indicate to roundup not to actually _send_ email
+# this var must contain a file to write the mail to
+SENDMAILDEBUG = os.environ.get('SENDMAILDEBUG', '')
+
+
# XXX actually _use_ FormError
class FormError(ValueError):
''' An "expected" exception occurred during form parsing.
# we don't want clients caching our dynamic pages
self.additional_headers['Cache-Control'] = 'no-cache'
self.additional_headers['Pragma'] = 'no-cache'
- self.additional_headers['Expires'] = 'Thu, 1 Jan 1970 00:00:00 GMT'
+
+ # expire this page 5 seconds from now
+ date = rfc822.formatdate(time.time() + 5)
+ self.additional_headers['Expires'] = date
# render the content
self.write(self.renderContext())
# remove aged otks
otks = self.db.otks
for sessid in otks.list():
- interval = now - okts.get(sessid, '__time')
+ interval = now - otks.get(sessid, '__time')
if interval > week:
- otk.destroy(sessid)
+ otks.destroy(sessid)
sessions.set('last_clean', last_use=time.time())
def determine_user(self):
self.write(file.get(nodeid, 'content'))
def serve_static_file(self, file):
+ ims = None
# see if there's an if-modified-since...
if hasattr(self.request, 'headers'):
ims = self.request.headers.getheader('if-modified-since')
raise NotModified
# we just want to serve up the file named
- mt = mimetypes.guess_type(str(file))[0]
+ file = str(file)
+ mt = mimetypes.guess_type(file)[0]
if not mt:
- mt = 'text/plain'
+ if file.endswith('.css'):
+ mt = 'text/css'
+ else:
+ mt = 'text/plain'
self.additional_headers['Content-Type'] = mt
self.additional_headers['Last-Modifed'] = rfc822.formatdate(lmt)
self.write(open(filename, 'rb').read())
content = StringIO.StringIO(content)
quopri.encode(content, body, 0)
- # now try to send the message
- try:
- # send the message as admin so bounces are sent there
- # instead of to roundup
- smtp = smtplib.SMTP(self.db.config.MAILHOST)
- smtp.sendmail(self.db.config.ADMIN_EMAIL, [to], message.getvalue())
- except socket.error, value:
- self.error_message.append("Error: couldn't send email: "
- "mailhost %s"%value)
- return 0
- except smtplib.SMTPException, value:
- self.error_message.append("Error: couldn't send email: %s"%value)
- return 0
+ if SENDMAILDEBUG:
+ # don't send - just write to a file
+ open(SENDMAILDEBUG, 'a').write('FROM: %s\nTO: %s\n%s\n'%(
+ self.db.config.ADMIN_EMAIL,
+ ', '.join(to),message.getvalue()))
+ else:
+ # now try to send the message
+ try:
+ # send the message as admin so bounces are sent there
+ # instead of to roundup
+ smtp = smtplib.SMTP(self.db.config.MAILHOST)
+ smtp.sendmail(self.db.config.ADMIN_EMAIL, [to],
+ message.getvalue())
+ except socket.error, value:
+ self.error_message.append("Error: couldn't send email: "
+ "mailhost %s"%value)
+ return 0
+ except smtplib.SMTPException, msg:
+ self.error_message.append("Error: couldn't send email: %s"%msg)
+ return 0
return 1
def registerPermission(self, props):
# create the new user
cl = self.db.user
# XXX we need to make the "default" page be able to display errors!
-# try:
- if 1:
+ try:
props['roles'] = self.instance.config.NEW_WEB_USER_ROLES
del props['__time']
self.userid = cl.create(**props)
# clear the props from the otk database
self.db.otks.destroy(otk)
self.db.commit()
-# except (ValueError, KeyError), message:
-# self.error_message.append(str(message))
-# return
+ except (ValueError, KeyError), message:
+ self.error_message.append(str(message))
+ return
# log the new user in
self.user = cl.get(self.userid, 'username')
# nice message
message = _('You are now registered, welcome!')
- # redirect to the item's edit page
- raise Redirect, '%suser%s?@ok_message=%s'%(
- self.base, self.userid, urllib.quote(message))
+ # redirect to the user's page
+ raise Redirect, '%suser%s?@ok_message=%s'%(self.base,
+ self.userid, urllib.quote(message))
def passResetAction(self):
''' Handle password reset requests.
# pull the rego information out of the otk database
otk = self.form['otk'].value
uid = self.db.otks.get(otk, 'uid')
+ if uid is None:
+ self.error_message.append('Invalid One Time Key!')
+ return
# re-open the database as "admin"
if self.user != 'admin':
newpw = ''.join([random.choice(self.chars) for x in range(8)])
cl = self.db.user
- # XXX we need to make the "default" page be able to display errors!
- # try:
- if 1:
+# XXX we need to make the "default" page be able to display errors!
+ try:
# set the password
cl.set(uid, password=password.Password(newpw))
# clear the props from the otk database
self.db.otks.destroy(otk)
self.db.commit()
- # except (ValueError, KeyError), message:
- # self.error_message.append(str(message))
- # return
+ except (ValueError, KeyError), message:
+ self.error_message.append(str(message))
+ return
# user info
address = self.db.user.get(uid, 'address')
See parsePropsFromForm and _editnodes for special variables
'''
# parse the props from the form
-# XXX reinstate exception handling
-# try:
- if 1:
+ try:
props, links = self.parsePropsFromForm()
-# except (ValueError, KeyError), message:
-# self.error_message.append(_('Error: ') + str(message))
-# return
+ except (ValueError, KeyError), message:
+ self.error_message.append(_('Error: ') + str(message))
+ return
# handle the props
-# XXX reinstate exception handling
-# try:
- if 1:
+ try:
message = self._editnodes(props, links)
-# except (ValueError, KeyError, IndexError), message:
-# self.error_message.append(_('Error: ') + str(message))
-# return
+ except (ValueError, KeyError, IndexError), message:
+ self.error_message.append(_('Error: ') + str(message))
+ return
# commit now that all the tricky stuff is done
self.db.commit()
# redirect to the item's edit page
- raise Redirect, '%s%s%s?@ok_message=%s'%(self.base, self.classname,
- self.nodeid, urllib.quote(message))
+ raise Redirect, '%s%s%s?@ok_message=%s&@template=%s'%(self.base,
+ self.classname, self.nodeid, urllib.quote(message),
+ urllib.quote(self.template))
def editItemPermission(self, props):
''' Determine whether the user has permission to edit this item.
special form values.
'''
# parse the props from the form
-# XXX reinstate exception handling
-# try:
- if 1:
+ try:
props, links = self.parsePropsFromForm()
-# except (ValueError, KeyError), message:
-# self.error_message.append(_('Error: ') + str(message))
-# return
+ except (ValueError, KeyError), message:
+ self.error_message.append(_('Error: ') + str(message))
+ return
# handle the props - edit or create
-# XXX reinstate exception handling
-# try:
- if 1:
- # create the context here
-# cn = self.classname
-# nid = self._createnode(cn, props[(cn, None)])
-# del props[(cn, None)]
-
+ try:
# when it hits the None element, it'll set self.nodeid
- messages = self._editnodes(props, links) #, {(cn, None): nid})
+ messages = self._editnodes(props, links)
-# except (ValueError, KeyError, IndexError), message:
-# # these errors might just be indicative of user dumbness
-# self.error_message.append(_('Error: ') + str(message))
-# return
+ except (ValueError, KeyError, IndexError), message:
+ # these errors might just be indicative of user dumbness
+ self.error_message.append(_('Error: ') + str(message))
+ return
# commit now that all the tricky stuff is done
self.db.commit()
# redirect to the new item's page
- raise Redirect, '%s%s%s?@ok_message=%s'%(self.base, self.classname,
- self.nodeid, urllib.quote(messages))
+ raise Redirect, '%s%s%s?@ok_message=%s&@template=%s'%(self.base,
+ self.classname, self.nodeid, urllib.quote(messages),
+ urllib.quote(self.template))
def newItemPermission(self, props):
''' Determine whether the user has permission to create (edit) this
'''
# check for permission
if not self.editItemPermission(props):
- raise PermissionError, 'You do not have permission to edit %s'%cn
+ raise Unauthorised, 'You do not have permission to edit %s'%cn
# make the changes
cl = self.db.classes[cn]
'''
# check for permission
if not self.newItemPermission(props):
- raise PermissionError, 'You do not have permission to create %s'%cn
+ raise Unauthorised, 'You do not have permission to create %s'%cn
# create the node and return its id
cl = self.db.classes[cn]
nodeid, values = values[0], values[1:]
found[nodeid] = 1
+ # see if the node exists
+ if cl.hasnode(nodeid):
+ exists = 1
+ else:
+ exists = 0
+
# confirm correct weight
if len(idlessprops) != len(values):
self.error_message.append(
# extract the new values
d = {}
for name, value in zip(idlessprops, values):
+ prop = cl.properties[name]
value = value.strip()
# only add the property if it has a value
if value:
# if it's a multilink, split it
- if isinstance(cl.properties[name], hyperdb.Multilink):
+ if isinstance(prop, hyperdb.Multilink):
value = value.split(':')
d[name] = value
+ elif exists:
+ # nuke the existing value
+ if isinstance(prop, hyperdb.Multilink):
+ d[name] = []
+ else:
+ d[name] = None
# perform the edit
- if cl.hasnode(nodeid):
+ if exists:
# edit existing
cl.set(nodeid, **d)
else:
else:
continue
else:
- if not self.form[key].value: continue
+ if not self.form[key].value:
+ continue
self.form.value.append(cgi.MiniFieldStorage('@filter', key))
# handle saving the query params