source: TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/authz/result_handler/redirect.py @ 6284

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/authz/result_handler/redirect.py@6284
Revision 6284, 4.6 KB checked in by pjkersha, 10 years ago (diff)

Preparing 1.4 release.

Line 
1"""WSGI Policy Enforcement Point basic result handler - returns a HTML access
2denied message to the client if the client is not authorized.
3
4Functionality in this module moved from original authz package location
5
6NERC DataGrid Project
7"""
8__author__ = "P J Kershaw"
9__date__ = "05/01/10"
10__copyright__ = "(C) 2010 Science and Technology Facilities Council"
11__contact__ = "Philip.Kershaw@stfc.ac.uk"
12__revision__ = "$Id: $"
13__license__ = "BSD - see LICENSE file in top-level directory"
14import logging
15log = logging.getLogger(__name__)
16
17from httplib import UNAUTHORIZED, FORBIDDEN
18
19from ndg.security.server.wsgi import NDGSecurityMiddlewareBase
20from ndg.security.server.wsgi.authz.result_handler import (
21    PEPResultHandlerMiddlewareBase, PEPResultHandlerMiddlewareConfigError)
22
23
24class HTTPRedirectPEPResultHandlerMiddleware(PEPResultHandlerMiddlewareBase):
25    """This middleware is invoked if access is denied to a given resource.  It
26    sets a redirect response to redirect the user's browser to a configured
27    URL.  This could be to provide a custom access denied message or interface.
28   
29    This middleware is incorporated into the call stack by passing it in to a
30    MultiHandler instance.  The MultiHandler is configured in the
31    AuthorizationMiddlewareBase class - see ndg.security.server.wsgi.authz.  The
32    MultiHandler is passed a checker method which determines whether to allow
33    access, or call this interface.   The checker is implemented in the
34    PEPFilter.  See ndg.security.server.wsgi.authz
35    """
36    REDIRECT_URI_PARAMNAME = 'redirectURI'
37   
38    def __init__(self, app, global_conf, prefix='', **app_conf):
39        '''
40        @type app: callable following WSGI interface
41        @param app: next middleware application in the chain     
42        @type global_conf: dict       
43        @param global_conf: PasteDeploy global configuration dictionary
44        @type prefix: basestring
45        @param prefix: prefix for configuration items
46        @type app_conf: dict       
47        @param app_conf: PasteDeploy application specific configuration
48        dictionary
49        '''
50        super(PEPResultHandlerMiddlewareBase, self).__init__(app, {})
51       
52        redirectURI = app_conf.get(prefix + \
53                    HTTPRedirectPEPResultHandlerMiddleware.REDIRECT_URI_PARAMNAME)
54        if redirectURI is None:
55            raise PEPResultHandlerMiddlewareConfigError("Missing required "
56                "parameter %r" % prefix + \
57                HTTPRedirectPEPResultHandlerMiddleware.REDIRECT_URI_PARAMNAME)
58   
59        self.redirectURI = redirectURI
60                 
61    @PEPResultHandlerMiddlewareBase.initCall
62    def __call__(self, environ, start_response):
63       
64        log.debug("PEPResultHandlerMiddleware.__call__ ...")
65        cls = HTTPRedirectPEPResultHandlerMiddleware
66       
67        session = self.environ.get(self.sessionKey)
68        if not self.isAuthenticated:
69            # This check is included as a precaution: this condition should be
70            # caught be the AuthNRedirectHandlerMiddleware or PEPFilter
71            log.warning("PEPResultHandlerMiddleware: user is not "
72                        "authenticated - setting HTTP 401 response")
73            return self._setErrorResponse(code=UNAUTHORIZED)
74        else:
75            # Get response message from PDP recorded by PEP
76            pepCtx = session.get(cls.PEPCTX_SESSION_KEYNAME, {})
77            pdpResponse = pepCtx.get(cls.PEPCTX_RESPONSE_SESSION_KEYNAME)
78            msg = getattr(pdpResponse, 'message', '') or ''
79            log.info("PEP returned access denied message: %r; redirecting to "
80                     "configured redirectURI=%r", msg, self.redirectURI)
81
82            return self.redirect()
83       
84    def redirect(self):
85        """Override NDGSecurityMiddlewareBase.redirect to pass uri attribute
86        explicitly
87       
88        @param uri: custom access denied response URI to redirect to
89        @type uri: basestring
90        @return: empty response - redirect is set in header
91        @rtype: list
92        """
93        return super(HTTPRedirectPEPResultHandlerMiddleware, self).redirect(
94                                                            self.redirectURI)
95       
96    def _setRedirectURI(self, uri):
97        if not isinstance(uri, basestring):
98            raise TypeError("Redirect URI must be set to string type")   
99         
100        self.__redirectURI = uri
101       
102    def _getRedirectURI(self):
103        return self.__redirectURI
104   
105    redirectURI = property(fget=_getRedirectURI,
106                           fset=_setRedirectURI,
107                           doc="URI to redirect to if access is denied")
Note: See TracBrowser for help on using the repository browser.