source: TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/myproxy.py @ 5838

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

Unit tested HTTPBasicAuthMiddleware. This will be used together MyProxyClientMiddleware? to make a myproxy-logon web service interface.

Line 
1"""Functionality for WSGI HTTPS proxy to MyProxy server.
2 
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "13/01/09"
7__copyright__ = "(C) 2009 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = "$Id$"
11import logging
12log = logging.getLogger(__name__)
13import re
14import httplib
15
16from myproxy.client import MyProxyClient
17from ndg.security.server.wsgi.authn import HTTPBasicAuthMiddleware
18
19class MyProxyClientMiddleware(object):
20    '''
21    HTTPS proxy to a MyProxy server to enable HTTPS type calls to MyProxy
22    '''
23    # Options for ini file
24    RE_PATH_MATCH_LIST_OPTNAME = 'rePathMatchList'
25   
26    PARAM_PREFIX = 'myproxy.'
27    MYPROXY_CLIENT_PARAM_PREFIX = 'client.'
28   
29    def __init__(self, app, global_conf, prefix=PARAM_PREFIX, **app_conf):
30        ''''''
31        super(MyProxyClientMiddleware, self).__init__(app, 
32                                                      global_conf, 
33                                                      prefix=prefix,
34                                                      *app_conf)
35        self.__myProxyClient = None
36
37        rePathMatchListParamName = prefix + \
38                            MyProxyClientMiddleware.RE_PATH_MATCH_LIST_OPTNAME
39        rePathMatchListVal = app_conf.get(rePathMatchListParamName, '')
40       
41        self.rePathMatchList = [re.compile(r) 
42                                for r in rePathMatchListVal.split()]
43
44        # Get MyProxyClient initialisation parameters
45        myProxyClientPrefix = prefix + \
46                            MyProxyClientMiddleware.MYPROXY_CLIENT_PARAM_PREFIX
47                           
48        myProxyClientKw = dict([(k.replace(myProxyClientPrefix, ''), v) 
49                                 for k,v in app_conf.items() 
50                                 if k.startswith(myProxyClientPrefix)])
51       
52        self.myProxyClient = MyProxyClient(**myProxyClientKw)
53
54    def _getMyProxyClient(self):
55        return self.__myProxyClient
56
57    def _setMyProxyClient(self, value):
58        if not isinstance(value, MyProxyClient):
59            raise TypeError('Expecting %r type for "myProxyClient" attribute '
60                            'got %r' % (MyProxyClient, type(value)))
61        self.__myProxyClient = value
62       
63    myProxyClient = property(fget=_getMyProxyClient,
64                             fset=_setMyProxyClient, 
65                             doc="MyProxyClient instance used to convert HTTPS"
66                                 " call into a call to a MyProxy server")
67
68    @NDGSecurityMiddlewareBase.initCall
69    def __call__(self, environ, start_response):
70        '''Intercept MyProxy call and relay to MyProxy server
71       
72        @type environ: dict
73        @param environ: WSGI environment variables dictionary
74        @type start_response: function
75        @param start_response: standard WSGI start response function
76        '''
77        log.debug("MyProxyClientMiddleware.__call__ ...")
78       
79        if not self._pathMatch():
80            return self._app(environ, start_response)
81        else:
82            try:
83                # TODO: get username/passphrase from upstream HTTP Basic Auth
84                # middleware
85                credentials = self.myProxyClient.logon(username, passphrase)
86            except Exception, e:
87                log.error(e)
88               
89                # TODO: fit to appropriate HTTP error code
90                raise
91           
92            response = '\n'.join(credentials)
93            start_response(MyProxyClientMiddleware.getStatusMessage(httplib.OK),
94                           [('Content-length', str(len(response))),
95                            ('Content-type', 'plain/text')])
96            return [response]
97       
98
99    def _pathMatch(self):
100        """Apply a list of regular expression matching patterns to the contents
101        of environ['PATH_INFO'], if any match, return True.  This method is
102        used to determine whether to apply SSL client authentication
103        """
104        path = self.pathInfo
105        for regEx in self.rePathMatchList:
106            if regEx.match(path):
107                return True
108           
109        return False   
110       
111       
112class MyProxyLogonMiddleware(NDGSecurityMiddlewareBase):
113    """HTTP Basic Auth interface to MyProxy logon"""
114    PARAM_PREFIX = 'myproxy.logon.'
115   
116    def __init__(self, app, app_conf, prefix=PARAM_PREFIX, **local_conf):
117        app = HTTPBasicAuthMiddleware(app, app_conf, **local_conf)
118        app = MyProxyClientMiddleware(app, app_conf, **local_conf)
Note: See TracBrowser for help on using the repository browser.