source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/utils/sessionmanagerclient.py @ 4513

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/utils/sessionmanagerclient.py@4513
Revision 4513, 8.7 KB checked in by pjkersha, 12 years ago (diff)

Added local Session Manager call test to combined services unit tests.

Line 
1"""NDG Security client - client interface classes to Session Manager
2
3Make requests for authentication and authorisation
4
5NERC Data Grid Project
6
7This software may be distributed under the terms of the Q Public License,
8version 1.0 or later.
9"""
10__author__ = "P J Kershaw"
11__date__ = "24/04/06"
12__copyright__ = "(C) 2007 STFC & NERC"
13__contact__ = "Philip.Kershaw@stfc.ac.uk"
14__revision__ = "$Id:sessionmanager.py 4373 2008-10-29 09:54:39Z pjkersha $"
15
16import logging
17log = logging.getLogger(__name__)
18
19import sys
20import os
21
22# Determine https http transport
23import urlparse
24
25from ZSI.wstools.Utility import HTTPResponse
26
27from ndg.security.common.wssecurity.dom import SignatureHandler
28from ndg.security.common.X509 import *
29from ndg.security.common.AttCert import AttCert, AttCertParse
30from ndg.security.common.m2CryptoSSLUtility import HTTPSConnection, \
31    HostCheck
32from ndg.security.common.zsi.httpproxy import ProxyHTTPConnection
33from ndg.security.common.zsi.sessionmanager.SessionManager_services import \
34                                                SessionManagerServiceLocator
35
36
37
38class SessionManagerClientError(Exception):
39    """Exception handling for WSGISessionManagerClient class"""
40
41class SessionNotFound(SessionManagerClientError):
42    """Raise when a session ID input doesn't match with an active session on
43    the Session Manager"""
44
45class SessionCertTimeError(SessionManagerClientError):
46    """Session's X.509 Cert. not before time is BEFORE the system time -
47    usually caused by server's clocks being out of sync.  Fix by all servers
48    running NTP"""
49
50class SessionExpired(SessionManagerClientError):
51    """Session's X.509 Cert. has expired"""
52
53class InvalidSession(SessionManagerClientError):
54    """Session is invalid"""
55
56class InvalidSessionManagerClientCtx(SessionManagerClientError):
57    """Session Manager ZSI Client is not initialised"""
58 
59class AttributeRequestDenied(SessionManagerClientError):
60    """Raise when a getAttCert call to the Attribute Authority is denied"""
61   
62    def __init__(self, *args, **kw):
63        """Raise exception for attribute request denied with option to give
64        caller hint to certificates that could used to try to obtain a
65        mapped certificate
66       
67        @type extAttCertList: list
68        @param extAttCertList: list of candidate Attribute Certificates that
69        could be used to try to get a mapped certificate from the target
70        Attribute Authority"""
71       
72        # Prevent None type setting
73        self.__extAttCertList = []
74        if 'extAttCertList' in kw and kw['extAttCertList'] is not None:
75            for ac in kw['extAttCertList']:
76                if isinstance(ac, basestring):
77                    ac = AttCertParse(ac)
78                elif not isinstance(ac, AttCert):
79                    raise SessionManagerClientError(
80                        "Input external Attribute Cert. must be AttCert type")
81                         
82                self.__extAttCertList += [ac]
83               
84            del kw['extAttCertList']
85           
86        Exception.__init__(self, *args, **kw)
87
88       
89    def __getExtAttCertList(self):
90        """Return list of candidate Attribute Certificates that could be used
91        to try to get a mapped certificate from the target Attribute Authority
92        """
93        return self.__extAttCertList
94
95    extAttCertList = property(fget=__getExtAttCertList,
96                              doc="list of candidate Attribute Certificates "
97                                  "that could be used to try to get a mapped "
98                                  "certificate from the target Attribute "
99                                  "Authority")
100
101class WSGISessionManagerClient(object):
102    """Client interface to Session Manager for WSGI based applications
103   
104    This class wraps the SOAP based web service client and alternate access to
105    a Session Manager in the same code stack via an environ keyword
106    """
107    environKey = "ndg.security.server.sessionmanager.SessionManager"
108   
109    def __init__(self, environKey=None, environ={}, 
110                 **SessionManagerClientKw):
111        """"""
112
113        log.debug("WSGISessionManagerClient.__init__ ...")
114       
115        self._environKey = environKey or WSGISessionManagerClient.environKey
116       
117        # Standard WSGI environment dict
118        self._environ = environ
119       
120        if 'uri' in SessionManagerClientKw:
121            self._soapClient = SessionManagerClient(**SessionManagerClientKw)
122
123    _sessionManagerInEnviron = lambda self: self._environKey in self._environ
124   
125    # Define as property for convenient call syntax
126    sessionManagerInEnviron = property(fget=_sessionManagerInEnviron,
127                                       doc="return True if a Session Manager "
128                                           "instance is available in "
129                                           "WSGI environ")
130   
131    _getSessionManager = lambda self:\
132                        self._environ[self._environKey].serviceSOAPBinding.sm
133    sessionManager = property(fget=_getSessionManager,
134                              doc="Session Manager local instance")
135   
136    def connect(self, username, **kw):
137        """Request a new user session from the Session Manager
138       
139        @type username: string
140        @param username: the username of the user to connect
141        """
142   
143        if self.sessionManagerInEnviron:
144            # Connect to local instance
145            res = self.sessionManager.connect(username=username, **kw)
146        else:
147            # Filter out keywords which apply to a Session Manager local
148            # instance call
149            kw.pop('userX509Cert', None)
150           
151            # Make connection to remote service
152            res = self._soapClient.connect(**kw)
153   
154            # Convert from unicode because unicode causes problems with
155            # M2Crypto private key load
156            res = tuple([isinstance(i,unicode) and str(i) or i for i in res])
157           
158        return res
159   
160   
161    def disconnect(self, **kw):
162        """Delete an existing user session from the Session Manager
163       
164        disconnect([userX509Cert=c]|[sessID=i])
165       
166        @type userX509Cert: string                 
167        @param userX509Cert: user's certificate used to identifier which session
168        to disconnect.  This arg is not needed if the message is signed with
169        the user cert or if sessID is set. 
170                               
171        @type sessID: string
172        @param sessID: session ID.  Input this as an alternative to userX509Cert
173        This arg is not needed if the message is signed with the user cert or
174        if userX509Cert keyword is."""
175   
176        # Make connection
177        self._soapClient.disconnect(**kw)
178       
179   
180    def getSessionStatus(self, userDN=None, sessID=None):
181        """Check for the existence of a session with a given
182        session ID / user certificate Distinguished Name
183       
184        disconnect([sessID=id]|[userDN=dn])
185       
186        @type userX509Cert: string                 
187        @param userX509Cert: user's certificate used to identifier which session
188        to disconnect.  This arg is not needed if the message is signed with
189        the user cert or if sessID is set. 
190                               
191        @type sessID: string
192        @param sessID: session ID.  Input this as an alternative to userX509Cert
193        This arg is not needed if the message is signed with the user cert or
194        if userX509Cert keyword is."""
195   
196        # Make connection
197        return self._soapClient.getSessionStatus(**kw)
198
199    def getAttCert(self, **kw):
200        """Request NDG Session Manager Web Service to retrieve an Attribute
201        Certificate from the given Attribute Authority and cache it in the
202        user's credential wallet held by the session manager.
203       
204        """
205        if self.sessionManagerInEnviron:
206            # Connect to local instance
207            res = self.sessionManager.getAttCert(username=username, **kw)
208        else:
209            # Filter out keywords which apply to a Session Manager local
210            # instance call
211            if 'userX509Cert' in kw:
212               
213           
214   
215           username=None,
216           userX509Cert=None,
217           sessID=None,
218           reqRole=None,
219           attributeAuthority=None,
220           attributeAuthorityURI=None,
221           mapFromTrustedHosts=None,
222           rtnExtAttCertList=None,
223           extAttCertList=None,
224           extTrustedHostList=None,
225           kw.pop('refreshAttCert', None)
226           kw.pop('attCertRefreshElapse', None)
227
228           userCert=None,
229           sessID=None,
230           attAuthorityURI=None,
231           reqRole=None,
232           mapFromTrustedHosts=True,
233           rtnExtAttCertList=False,
234           extAttCertList=[],
235           extTrustedHostList=[]):   
Note: See TracBrowser for help on using the repository browser.