source: permredirectplugin/trunk/permredirect/filter.py @ 12446

Last change on this file since 12446 was 12446, checked in by ejucovy, 11 years ago

fixes #10709 -- don't explode with a system error if sys.exc_info()[0] is None. also, add some logging code in that situation, because i don't understand when it happens.

File size: 3.0 KB
Line 
1# Created by Noah Kantrowitz on 2007-08-27.
2# Copyright (c) 2007-2008 Noah Kantrowitz. All rights reserved.
3from pprint import pformat
4import sys
5
6from trac.core import *
7from trac.config import BoolOption
8from trac.web.api import IRequestFilter, RequestDone
9from trac.perm import PermissionError
10from trac.admin.web_ui import AdminModule
11
12class PermRedirectModule(Component):
13    """Redirect users to the login screen on PermissionError."""
14   
15    implements(IRequestFilter)
16
17    redirect_login_https = BoolOption(
18        'permredirect', 'redirect_login_https', 'false',
19        """Redirect all requests to /login/ to HTTPS""")
20
21    redirect_login = BoolOption(
22        'permredirect', 'redirect_login', 'true',
23        """Redirect unauthenticated users to /login/ on PermissionError""")
24
25    # IRequestFilter methods
26    def pre_process_request(self, req, handler):
27        if not self.redirect_login_https:
28            return handler
29
30        path = req.base_path + req.path_info
31
32        pos = req.base_url.find(':')
33        base_scheme = req.base_url[:pos]
34        base_noscheme = req.base_url[pos:]
35        base_noscheme_norm = base_noscheme.rstrip('/')
36        if path == req.href.login() and base_scheme == 'http':
37            login_url = 'https' + base_noscheme_norm + req.path_info
38            if req.query_string:
39                login_url = login_url + '?' + req.query_string
40            req.redirect(login_url)
41        return handler
42           
43    def post_process_request(self, req, template, data, content_type):   
44        if not self.redirect_login:
45            return template, data, content_type
46
47        if template is None:
48            # Some kind of exception in progress
49            if req.authname != 'anonymous':
50                # Already logged in
51                return template, data, content_type
52           
53            ref_url = req.base_url + req.path_info
54            if req.query_string:
55                ref_url = ref_url + "?" + req.query_string
56
57            exctype, exc = sys.exc_info()[0:2]
58            if exctype is None:
59                self.log.debug("template and exctype both None for request "
60                               "to %s: %s" % (ref_url, pformat(req.environ)))
61                return template, data, content_type
62
63           
64            login_url = req.href.login(referer=ref_url)
65
66            if issubclass(exctype, PermissionError):
67                req.redirect(login_url)
68           
69            try:
70                if req.path_info.startswith('/admin') and \
71                   not AdminModule(self.env)._get_panels(req)[0]:
72                    # No admin panels available, assume user should log in.
73                    req.redirect(login_url)
74            except RequestDone:
75                # Reraise on redirect
76                raise
77            except Exception:
78                # It is possible the error we got called on happened inside
79                # the _get_panels call. Be sure to ignore it.
80                pass
81           
82        return template, data, content_type
83
Note: See TracBrowser for help on using the repository browser.