diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
index 793a0d8472b32b4f183910948e953e83e2c005a4..11a22172e9c1f69437c139afa66525d78d6986a1 100644 (file)
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
import base64, binascii, cgi, codecs, mimetypes, os
import quopri, random, re, rfc822, stat, sys, time
import socket, errno
+from traceback import format_exc
from roundup import roundupdb, date, hyperdb, password
from roundup.cgi import templating, cgitb, TranslationService
from roundup.anypy import http_
from roundup.anypy import urllib_
+from email.MIMEBase import MIMEBase
+from email.MIMEText import MIMEText
+from email.MIMEMultipart import MIMEMultipart
+
def initialiseSecurity(security):
'''Create some Permissions and Roles on the security object
if not self.instance.config.WEB_DEBUG:
exc_info = sys.exc_info()
subject = "Error: %s" % exc_info[1]
- self.send_html_to_admin(subject, html)
+ self.send_error_to_admin(subject, html, format_exc())
self.write_html(self._(error_message))
else:
self.write_html(html)
"""
# allow Anonymous to use the "login" and "register" actions (noting
# that "register" has its own "Register" permission check)
+
if ':action' in self.form:
- action = self.form[':action'].value.lower()
+ action = self.form[':action']
elif '@action' in self.form:
- action = self.form['@action'].value.lower()
+ action = self.form['@action']
else:
- action = None
+ action = ''
+ if isinstance(action, list):
+ raise SeriousError('broken form: multiple @action values submitted')
+ elif action != '':
+ action = action.value.lower()
if action in ('login', 'register'):
return
raise Unauthorised(self._("You are not allowed to view "
"this file."))
- mime_type = klass.get(nodeid, 'type')
+ try:
+ mime_type = klass.get(nodeid, 'type')
+ except IndexError, e:
+ raise NotFound(e)
# Can happen for msg class:
if not mime_type:
mime_type = 'text/plain'
self.additional_headers['Content-Length'] = str(len(content))
self.write(content)
- def send_html_to_admin(self, subject, content):
-
+ def send_error_to_admin(self, subject, html, txt):
+ """Send traceback information to admin via email.
+ We send both, the formatted html (with more information) and
+ the text version of the traceback. We use
+ multipart/alternative so the receiver can chose which version
+ to display.
+ """
to = [self.mailer.config.ADMIN_EMAIL]
- message = self.mailer.get_standard_message(to, subject)
- # delete existing content-type headers
- del message['Content-type']
- message['Content-type'] = 'text/html; charset=utf-8'
- message.set_payload(content)
- encode_quopri(message)
- self.mailer.smtp_send(to, str(message))
+ message = MIMEMultipart('alternative')
+ self.mailer.set_message_attributes(message, to, subject)
+ part = MIMEBase('text', 'html')
+ part.set_charset('utf-8')
+ part.set_payload(html)
+ encode_quopri(part)
+ message.attach(part)
+ part = MIMEText(txt)
+ message.attach(part)
+ self.mailer.smtp_send(to, message.as_string())
def renderFrontPage(self, message):
"""Return the front page of the tracker."""
result = result.replace('</body>', s)
return result
except templating.NoTemplate, message:
- return '<strong>%s</strong>'%message
+ return '<strong>%s</strong>'%cgi.escape(str(message))
except templating.Unauthorised, message:
- raise Unauthorised(str(message))
+ raise Unauthorised(cgi.escape(str(message)))
except:
# everything else
if self.instance.config.WEB_DEBUG:
# If possible, send the HTML page template traceback
# to the administrator.
subject = "Templating Error: %s" % exc_info[1]
- self.send_html_to_admin(subject, cgitb.pt_html())
+ self.send_error_to_admin(subject, cgitb.pt_html(), format_exc())
# Now report the error to the user.
return self._(error_message)
except:
present their messages to the user.
"""
if ':action' in self.form:
- action = self.form[':action'].value.lower()
+ action = self.form[':action']
elif '@action' in self.form:
- action = self.form['@action'].value.lower()
+ action = self.form['@action']
else:
return None
+ if isinstance(action, list):
+ raise SeriousError('broken form: multiple @action values submitted')
+ else:
+ action = action.value.lower()
+
try:
action_klass = self.get_action_class(action)