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

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

Initial code for a HTTPS WSGI interface to front a MyProxy? service.

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
17
18class MyProxyClientMiddleware(object):
19    '''
20    HTTPS proxy to a MyProxy server to enable HTTPS type calls to MyProxy
21    '''
22    # Options for ini file
23    RE_PATH_MATCH_LIST_OPTNAME = 'rePathMatchList'
24   
25    PARAM_PREFIX = 'myproxy.'
26    MYPROXY_CLIENT_PARAM_PREFIX = 'client.'
27   
28    def __init__(self, app, global_conf, prefix=PARAM_PREFIX, **app_conf):
29        ''''''
30        super(MyProxyClientMiddleware, self).__init__(app, 
31                                                      global_conf, 
32                                                      prefix=prefix,
33                                                      *app_conf)
34        self.__myProxyClient = None
35
36        rePathMatchListParamName = prefix + \
37                    MyProxyClientMiddleware.RE_PATH_MATCH_LIST_OPTNAME
38        rePathMatchListVal = app_conf.get(rePathMatchListParamName, '')
39       
40        self.rePathMatchList = [re.compile(r) 
41                                for r in rePathMatchListVal.split()]
42
43        # Get MyProxyClient initialisation parameters
44        myProxyClientPrefix = prefix + \
45                            MyProxyClientMiddleware.MYPROXY_CLIENT_PARAM_PREFIX
46                           
47        myProxyClientKw = dict([(k.replace(myProxyClientPrefix, ''), v) 
48                                 for k,v in app_conf.items() 
49                                 if k.startswith(myProxyClientPrefix)])
50       
51        self.myProxyClient = MyProxyClient(**myProxyClientKw)
52
53    def _getMyProxyClient(self):
54        return self.__myProxyClient
55
56    def _setMyProxyClient(self, value):
57        if not isinstance(value, MyProxyClient):
58            raise TypeError('Expecting %r type for "myProxyClient" attribute '
59                            'got %r' % (MyProxyClient, type(value)))
60        self.__myProxyClient = value
61       
62    myProxyClient = property(fget=_getMyProxyClient,
63                             fset=_setMyProxyClient, 
64                             doc="MyProxyClient instance used to convert HTTPS"
65                                 " call into a call to a MyProxy server")
66
67    @NDGSecurityMiddlewareBase.initCall
68    def __call__(self, environ, start_response):
69        '''Intercept MyProxy call and relay to MyProxy server
70       
71        @type environ: dict
72        @param environ: WSGI environment variables dictionary
73        @type start_response: function
74        @param start_response: standard WSGI start response function
75        '''
76        log.debug("MyProxyClientMiddleware.__call__ ...")
77       
78        if not self._pathMatch():
79            return self._app(environ, start_response)
80        else:
81            try:
82                # TODO: get username/passphrase from upstream HTTP Basic Auth
83                # middleware
84                credentials = self.myProxyClient.logon(username, passphrase)
85            except Exception, e:
86                log.error(e)
87               
88                # TODO: fit to appropriate HTTP error code
89                raise
90           
91            response = '\n'.join(credentials)
92            start_response(MyProxyClientMiddleware.getStatusMessage(httplib.OK),
93                           [('Content-length', str(len(response))),
94                            ('Content-type', 'plain/text')])
95            return [response]
96       
97
98    def _pathMatch(self):
99        """Apply a list of regular expression matching patterns to the contents
100        of environ['PATH_INFO'], if any match, return True.  This method is
101        used to determine whether to apply SSL client authentication
102        """
103        path = self.pathInfo
104        for regEx in self.rePathMatchList:
105            if regEx.match(path):
106                return True
107           
108        return False   
109       
Note: See TracBrowser for help on using the repository browser.