| 3 | | Here is an update of SecSessionPlugin which works on Trac 0.10dev. |
| 4 | | It also adds a config hook which lets you use it when your Trac |
| 5 | | runs behind a proxy server. |
| 6 | | |
| 7 | | As pacopablo (its author) hasn't given a contact info and uploading |
| 8 | | attachments is broken ATM, I just paste the updated `secsession.py` here. |
| 9 | | |
| 10 | | {{{ |
| 11 | | #!python |
| 12 | | |
| 13 | | from trac.core import * |
| 14 | | from trac.web import IRequestFilter |
| 15 | | |
| 16 | | class SecureSessionFilter(Component): |
| 17 | | implements(IRequestFilter) |
| 18 | | |
| 19 | | def pre_process_request(self, req, handler): |
| 20 | | # self.log.info("setting up the match") ### 'twas too much noize |
| 21 | | |
| 22 | | # We provide a config hook for checking if the request is |
| 23 | | # secure. Simply checking the scheme is not the appropriate |
| 24 | | # choice in all case -- eg., if trac runs behind a proxy |
| 25 | | # server, then it will get simple http requests from the |
| 26 | | # proxy and we have to analyze headers to find out if |
| 27 | | # the original request was secure or not. |
| 28 | | # |
| 29 | | # Currently we can directly match a request attribute |
| 30 | | # as "@<attr> = <val>" or a http header line as "<hdlr> = <val>". |
| 31 | | # This could be generalized by, eg., taking a list of such |
| 32 | | # patterns, whatever. |
| 33 | | key, val = [ x.strip() for x in self.config.get('secsession', |
| 34 | | 'secpattern', |
| 35 | | '@scheme=https' |
| 36 | | ).split('=', 1) ] |
| 37 | | if key[0] == '@': |
| 38 | | myval = getattr(req, key[1:]) |
| 39 | | else: |
| 40 | | myval = req.get_header(key) |
| 41 | | |
| 42 | | if unicode(myval) != val: |
| 43 | | # Auth info is not available at the time of invoking filters, |
| 44 | | # so we can't yet make the decision about redirecting. |
| 45 | | # |
| 46 | | # Therefore we just wrap the handler into our redirection policy. |
| 47 | | # When the handler will be invoked, auth info will be there; |
| 48 | | # if auth is anon, our wrapper will call the original |
| 49 | | # handler, else it will perform the redirect. |
| 50 | | handler = SecureSessionWrapper(handler, self) |
| 51 | | return handler |
| 52 | | |
| 53 | | def post_process_request(self, req, template, content_type): |
| 54 | | return template, content_type |
| 55 | | |
| 56 | | |
| 57 | | class SecureSessionWrapper(object): |
| 58 | | |
| 59 | | def __init__(self, in_handler, filter): |
| 60 | | self.in_handler = in_handler |
| 61 | | self.config = filter.config |
| 62 | | self.log = in_handler.log |
| 63 | | |
| 64 | | def process_request(self, req): |
| 65 | | |
| 66 | | if not req.authname or req.authname == 'anonymous': |
| 67 | | return self.in_handler.process_request(req) |
| 68 | | |
| 69 | | self.log.info("redirect to secure site:") |
| 70 | | secport = self.config.getint('secsession', 'secport', 443) |
| 71 | | port = '' |
| 72 | | if secport != 443: |
| 73 | | port = ':%d' % secport |
| 74 | | |
| 75 | | req.redirect(''.join(['https://', |
| 76 | | req.server_name, |
| 77 | | port, |
| 78 | | req.href(), |
| 79 | | req.path_info |
| 80 | | ]) ) |
| 81 | | }}} |
| 82 | | |
| | 3 | Hint: A contributed modification of the SecSessionPlugin for trac-0.10dev has been committed to the [source:secsessionplugin/0.10 0.10 branch] of that plugin. |