Mercurial > p > roundup > code
comparison roundup/cgi/client.py @ 1977:f96592a7c357
changes to support the new templating Unauthorised exception.
bugfix in file download
fixed display of feedback messages in some situations [SF#739545]
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 19 Jan 2004 23:56:07 +0000 |
| parents | b019d0194d27 |
| children | 910b39f8c5b8 |
comparison
equal
deleted
inserted
replaced
| 1976:3a4abf6d48c2 | 1977:f96592a7c357 |
|---|---|
| 1 # $Id: client.py,v 1.151 2004-01-17 01:59:33 richard Exp $ | 1 # $Id: client.py,v 1.152 2004-01-19 23:56:07 richard Exp $ |
| 2 | 2 |
| 3 __doc__ = """ | 3 __doc__ = """ |
| 4 WWW request handler (also used in the stand-alone server). | 4 WWW request handler (also used in the stand-alone server). |
| 5 """ | 5 """ |
| 6 | 6 |
| 8 import binascii, Cookie, time, random, MimeWriter, smtplib, socket, quopri | 8 import binascii, Cookie, time, random, MimeWriter, smtplib, socket, quopri |
| 9 import stat, rfc822 | 9 import stat, rfc822 |
| 10 | 10 |
| 11 from roundup import roundupdb, date, hyperdb, password, token, rcsv | 11 from roundup import roundupdb, date, hyperdb, password, token, rcsv |
| 12 from roundup.i18n import _ | 12 from roundup.i18n import _ |
| 13 from roundup.cgi.templating import Templates, HTMLRequest, NoTemplate | 13 from roundup.cgi import templating, cgitb |
| 14 from roundup.cgi import cgitb | |
| 15 from roundup.cgi.PageTemplates import PageTemplate | 14 from roundup.cgi.PageTemplates import PageTemplate |
| 16 from roundup.rfc2822 import encode_header | 15 from roundup.rfc2822 import encode_header |
| 17 from roundup.mailgw import uidFromAddress | 16 from roundup.mailgw import uidFromAddress |
| 18 from roundup.mailer import Mailer, MessageSendError | 17 from roundup.mailer import Mailer, MessageSendError |
| 19 | 18 |
| 221 serve up a file from the tracker "html" directory | 220 serve up a file from the tracker "html" directory |
| 222 - Unauthorised (generally raised by an action) | 221 - Unauthorised (generally raised by an action) |
| 223 the action is cancelled, the request is rendered and an error | 222 the action is cancelled, the request is rendered and an error |
| 224 message is displayed indicating that permission was not | 223 message is displayed indicating that permission was not |
| 225 granted for the action to take place | 224 granted for the action to take place |
| 225 - templating.Unauthorised (templating action not permitted) | |
| 226 raised by an attempted rendering of a template when the user | |
| 227 doesn't have permission | |
| 226 - NotFound (raised wherever it needs to be) | 228 - NotFound (raised wherever it needs to be) |
| 227 percolates up to the CGI interface that called the client | 229 percolates up to the CGI interface that called the client |
| 228 ''' | 230 ''' |
| 229 self.ok_message = [] | 231 self.ok_message = [] |
| 230 self.error_message = [] | 232 self.error_message = [] |
| 270 except NotModified: | 272 except NotModified: |
| 271 # send the 304 response | 273 # send the 304 response |
| 272 self.request.send_response(304) | 274 self.request.send_response(304) |
| 273 self.request.end_headers() | 275 self.request.end_headers() |
| 274 except Unauthorised, message: | 276 except Unauthorised, message: |
| 275 self.classname = None | 277 # users may always see the front page |
| 278 self.classname = self.nodeid = None | |
| 276 self.template = '' | 279 self.template = '' |
| 277 self.error_message.append(message) | 280 self.error_message.append(message) |
| 278 self.write(self.renderContext()) | 281 self.write(self.renderContext()) |
| 279 except NotFound: | 282 except NotFound: |
| 280 # pass through | 283 # pass through |
| 411 ok_message = clean_message(ok_message) | 414 ok_message = clean_message(ok_message) |
| 412 elif self.FV_ERROR_MESSAGE.match(key): | 415 elif self.FV_ERROR_MESSAGE.match(key): |
| 413 error_message = self.form[key].value | 416 error_message = self.form[key].value |
| 414 error_message = clean_message(error_message) | 417 error_message = clean_message(error_message) |
| 415 | 418 |
| 419 # see if we were passed in a message | |
| 420 if ok_message: | |
| 421 self.ok_message.append(ok_message) | |
| 422 if error_message: | |
| 423 self.error_message.append(error_message) | |
| 424 | |
| 416 # determine the classname and possibly nodeid | 425 # determine the classname and possibly nodeid |
| 417 path = self.path.split('/') | 426 path = self.path.split('/') |
| 418 if not path or path[0] in ('', 'home', 'index'): | 427 if not path or path[0] in ('', 'home', 'index'): |
| 419 if template_override is not None: | 428 if template_override is not None: |
| 420 self.template = template_override | 429 self.template = template_override |
| 453 | 462 |
| 454 # see if we have a template override | 463 # see if we have a template override |
| 455 if template_override is not None: | 464 if template_override is not None: |
| 456 self.template = template_override | 465 self.template = template_override |
| 457 | 466 |
| 458 # see if we were passed in a message | |
| 459 if ok_message: | |
| 460 self.ok_message.append(ok_message) | |
| 461 if error_message: | |
| 462 self.error_message.append(error_message) | |
| 463 | |
| 464 def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')): | 467 def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')): |
| 465 ''' Serve the file from the content property of the designated item. | 468 ''' Serve the file from the content property of the designated item. |
| 466 ''' | 469 ''' |
| 467 m = dre.match(str(designator)) | 470 m = dre.match(str(designator)) |
| 468 if not m: | 471 if not m: |
| 472 self.opendb('admin') | 475 self.opendb('admin') |
| 473 klass = self.db.getclass(classname) | 476 klass = self.db.getclass(classname) |
| 474 | 477 |
| 475 # make sure we have the appropriate properties | 478 # make sure we have the appropriate properties |
| 476 props = klass.getprops() | 479 props = klass.getprops() |
| 477 if not pops.has_key('type'): | 480 if not props.has_key('type'): |
| 478 raise NotFound, designator | 481 raise NotFound, designator |
| 479 if not pops.has_key('content'): | 482 if not props.has_key('content'): |
| 480 raise NotFound, designator | 483 raise NotFound, designator |
| 481 | 484 |
| 482 mime_type = klass.get(nodeid, 'type') | 485 mime_type = klass.get(nodeid, 'type') |
| 483 content = klass.get(nodeid, 'content') | 486 content = klass.get(nodeid, 'content') |
| 484 lmt = klass.get(nodeid, 'activity').timestamp() | 487 lmt = klass.get(nodeid, 'activity').timestamp() |
| 537 def renderContext(self): | 540 def renderContext(self): |
| 538 ''' Return a PageTemplate for the named page | 541 ''' Return a PageTemplate for the named page |
| 539 ''' | 542 ''' |
| 540 name = self.classname | 543 name = self.classname |
| 541 extension = self.template | 544 extension = self.template |
| 542 pt = Templates(self.instance.config.TEMPLATES).get(name, extension) | 545 pt = templating.Templates(self.instance.config.TEMPLATES).get(name, |
| 546 extension) | |
| 543 | 547 |
| 544 # catch errors so we can handle PT rendering errors more nicely | 548 # catch errors so we can handle PT rendering errors more nicely |
| 545 args = { | 549 args = { |
| 546 'ok_message': self.ok_message, | 550 'ok_message': self.ok_message, |
| 547 'error_message': self.error_message | 551 'error_message': self.error_message |
| 549 try: | 553 try: |
| 550 # let the template render figure stuff out | 554 # let the template render figure stuff out |
| 551 result = pt.render(self, None, None, **args) | 555 result = pt.render(self, None, None, **args) |
| 552 self.additional_headers['Content-Type'] = pt.content_type | 556 self.additional_headers['Content-Type'] = pt.content_type |
| 553 return result | 557 return result |
| 554 except NoTemplate, message: | 558 except templating.NoTemplate, message: |
| 555 return '<strong>%s</strong>'%message | 559 return '<strong>%s</strong>'%message |
| 560 except templating.Unauthorised, message: | |
| 561 raise Unauthorised, str(message) | |
| 556 except: | 562 except: |
| 557 # everything else | 563 # everything else |
| 558 return cgitb.pt_html() | 564 return cgitb.pt_html() |
| 559 | 565 |
| 560 # these are the actions that are available | 566 # these are the actions that are available |
| 1305 self.form.value.append(cgi.MiniFieldStorage('@filter', key)) | 1311 self.form.value.append(cgi.MiniFieldStorage('@filter', key)) |
| 1306 | 1312 |
| 1307 # handle saving the query params | 1313 # handle saving the query params |
| 1308 if queryname: | 1314 if queryname: |
| 1309 # parse the environment and figure what the query _is_ | 1315 # parse the environment and figure what the query _is_ |
| 1310 req = HTMLRequest(self) | 1316 req = templating.HTMLRequest(self) |
| 1311 | 1317 |
| 1312 # The [1:] strips off the '?' character, it isn't part of the | 1318 # The [1:] strips off the '?' character, it isn't part of the |
| 1313 # query string. | 1319 # query string. |
| 1314 url = req.indexargs_href('', {})[1:] | 1320 url = req.indexargs_href('', {})[1:] |
| 1315 | 1321 |
