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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/utils/sessionmanagerclient.py@4890
Revision 4890, 11.9 KB checked in by pjkersha, 12 years ago (diff)
  • fixed inclusion of badc templates and static content for SSO in ndg.security.server egg
  • fix to SSO logout controller to use WSGI client wrapper for Session Manager call
  • Refactored SM and AA WSGI client wrappers adding a base class in clientbase module and including check for match for URI request by client to URI endpoint of WSGI service running locally.
Line 
1"""NDG Security
2
3Client interface to Session Manager for WSGI based applications
4
5NERC DataGrid Project
6"""
7__author__ = "P J Kershaw"
8__date__ = "27/11/08"
9__copyright__ = "(C) 2009 Science and Technology Facilities Council"
10__license__ = "BSD - see LICENSE file in top-level directory"
11__contact__ = "Philip.Kershaw@stfc.ac.uk"
12__revision__ = "$Id$"
13import logging
14log = logging.getLogger(__name__)
15
16import sys
17import os
18
19from ndg.security.server.wsgi.utils.clientbase import WSGIClientBase
20from ndg.security.server.wsgi.utils.attributeauthorityclient import \
21    WSGIAttributeAuthorityClient
22
23# Session Manager Authentication interface ...
24from ndg.security.server.sessionmanager import AuthNServiceError, \
25    AuthNServiceInvalidCredentials, AuthNServiceRetrieveError, \
26    AuthNServiceInitError, AuthNServiceConfigError
27
28# Session Manager SOAP client interface
29from ndg.security.common.sessionmanager import SessionManagerClient
30   
31# Import exception types from Session Manager and Session Manager client to
32# give caller some capability to trap errors
33# Session Manager server side exceptions ...
34from ndg.security.server.sessionmanager import SessionManagerError, \
35    UserSessionExpired, UserSessionX509CertNotBeforeTimeError, \
36    InvalidUserSession, CredentialWalletAttributeRequestDenied
37   
38from ndg.security.server.sessionmanager import SessionNotFound as \
39    _SrvSessionNotFound
40
41# ... and client side exceptions ...
42from ndg.security.common.sessionmanager import SessionNotFound as \
43    _ClntSessionNotFound
44
45from ndg.security.common.sessionmanager import SessionExpired as \
46    _ClntSessionExpired
47
48from ndg.security.common.sessionmanager import InvalidSession as \
49    _ClntInvalidSession
50 
51from ndg.security.common.sessionmanager import AttributeRequestDenied as \
52    _ClntAttributeRequestDenied
53     
54from ndg.security.common.sessionmanager import InvalidSessionManagerClientCtx,\
55    SessionManagerClientError, SessionCertTimeError
56
57SessionNotFound = (_SrvSessionNotFound, _ClntSessionNotFound)
58
59# Combine client and server session not before time error exceptions to
60# enable easier exception handling for a WSGISessionManagerClient caller. 
61# See SessionNotFound.__doc__ for more details of reasoning
62SessionNotBeforeTimeError = (UserSessionX509CertNotBeforeTimeError, 
63                             SessionCertTimeError)
64
65# Combine client and server session expired exceptions to enable easier
66# exception handling for a WSGISessionManagerClient caller.  See
67# SessionNotFound.__doc__ for more details of reasoning
68SessionExpired = (UserSessionExpired, _ClntSessionExpired)
69
70# Combine client and server invalid session exceptions to enable easier
71# exception handling for a WSGISessionManagerClient caller.  See
72# SessionNotFound.__doc__ for more details of reasoning"""
73InvalidSession = (InvalidUserSession, _ClntInvalidSession)
74   
75# Combine client and server invalid session exceptions to enable easier
76# exception handling for a WSGISessionManagerClient caller.  See
77# SessionNotFound.__doc__ for more details of reasoning
78AttributeRequestDenied = (CredentialWalletAttributeRequestDenied, 
79                          _ClntAttributeRequestDenied)
80
81# End of server/client side exception combinations
82
83       
84class WSGISessionManagerClientError(Exception):
85    """Base class exception for WSGI Session Manager client errors"""
86   
87class WSGISessionManagerClientConfigError(WSGISessionManagerClientError):
88    """Configuration error for WSGI Session Manager Client"""
89   
90class WSGISessionManagerClient(WSGIClientBase):
91    """Client interface to Session Manager for WSGI based applications
92   
93    This class wraps the SOAP based web service client and alternate access to
94    a Session Manager instance in the same code stack available via an environ
95    keyword
96   
97    @type environKey: basestring
98    @cvar environKey: default WSGI environ keyword name for reference to a
99    local Session Manager instance.  Override with the environKey keyword to
100    __init__
101   
102    @type attributeAuthorityEnvironKey: basestring
103    @cvar attributeAuthorityEnvironKey: default WSGI environ keyword name for
104    reference to a local Attribute Authority instance used in calls to
105    getAttCert().  Override with the attributeAuthorityEnvironKey keyword to
106    __init__
107    """
108    environKey = "ndg.security.server.wsgi.sessionManagerFilter"
109    attributeAuthorityEnvironKey = WSGIAttributeAuthorityClient.environKey
110       
111    _getRef = lambda self:self._environ[self._environKey].serviceSOAPBinding.sm
112    ref = property(fget=_getRef, doc="local session manager instance")
113
114   
115    def __init__(self, 
116                 environKey=None, 
117                 attributeAuthorityEnvironKey=None,
118                 environ={}, 
119                 **soapClientKw):
120 
121        log.debug("WSGISessionManagerClient.__init__ ...")
122       
123        self._environKey = environKey or WSGISessionManagerClient.environKey
124        self._attributeAuthorityEnvironKey = attributeAuthorityEnvironKey or \
125                        WSGISessionManagerClient.attributeAuthorityEnvironKey
126                       
127        # Standard WSGI environment dict
128        self._environ = environ
129       
130        if soapClientKw.get('uri'):
131            self._client = SessionManagerClient(**soapClientKw)
132        else:
133            self._client = None
134
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.refInEnviron:
144            log.debug("Connecting to local Session Manager instance")
145            if 'username' in kw:
146                raise TypeError("connect() got an unexpected keyword argument "
147                                "'username'")
148               
149            # Connect to local instance
150            res = self.ref.connect(username=username, **kw)
151           
152        elif self._client is None:           
153            raise WSGISessionManagerClientConfigError("No reference to a "
154                        "local Session Manager is set and no SOAP client "
155                        "to a remote service has been initialized")
156        else:
157            log.debug("Connecting to remote Session Manager service")
158           
159            # Filter out keywords which apply to a Session Manager local
160            # instance call
161            kw.pop('userX509Cert', None)
162           
163            # Make connection to remote service
164            res = self._client.connect(username, **kw)
165   
166            # Convert from unicode because unicode causes problems with
167            # M2Crypto private key load
168            res = tuple([isinstance(i,unicode) and str(i) or i for i in res])
169           
170        return res
171   
172   
173    def disconnect(self, **kw):
174        """Delete an existing user session from the Session Manager
175       
176        @type **kw: dict
177        @param **kw: disconnect keywords applicable to
178        ndg.security.server.sessionmanager.SessionManager.getSessionStatus and
179        ndg.security.common.sessionmanager.SessionManagerClient.getSessionStatus
180        the SOAP client"""
181   
182        # Modify keywords according to correct interface for server side /
183        # SOAP client
184        if self.refInEnviron:
185            if 'userDN' in kw:
186                log.warning('Removing keyword "userDN": this is not supported '
187                            'for calls to ndg.security.server.sessionmanager.'
188                            'SessionManager.deleteUserSession')
189                kw.pop('userX509Cert', None)
190               
191            self.ref.deleteUserSession(**kw)
192           
193        elif self._client is None:           
194            raise WSGISessionManagerClientConfigError("No reference to a "
195                        "local Session Manager is set and no SOAP client "
196                        "to a remote service has been initialized")
197        else:
198            if 'userX509Cert' in kw:
199                kw['userDN'] = kw.pop('userX509Cert').dn
200               
201            self._client.disconnect(**kw)
202       
203   
204    def getSessionStatus(self, **kw):
205        """Check for the existence of a session with a given
206        session ID / user certificate Distinguished Name
207                               
208        @type **kw: dict
209        @param **kw: disconnect keywords applicable to
210        ndg.security.server.sessionmanager.SessionManager.getSessionStatus and
211        ndg.security.common.sessionmanager.SessionManagerClient.getSessionStatus
212        the SOAP client"""
213   
214        if self.refInEnviron:
215            return self.ref.getSessionStatus(**kw)
216       
217        elif self._client is None:           
218            raise WSGISessionManagerClientConfigError("No reference to a "
219                        "local Session Manager is set and no SOAP client "
220                        "to a remote service has been initialized")
221        else:
222            return self._client.getSessionStatus(**kw)
223   
224
225
226    def getAttCert(self, **kw):
227        """Request NDG Session Manager to retrieve an Attribute
228        Certificate from the given Attribute Authority and cache it in the
229        user's credential wallet held by the session manager.
230       
231        @type **kw: dict
232        @param **kw: disconnect keywords applicable to
233        ndg.security.server.sessionmanager.SessionManager.getAttCert and
234        ndg.security.common.sessionmanager.SessionManagerClient.getAttCert
235        the SOAP client
236        """
237       
238        if self.refInEnviron:
239            # Connect to local instance of Session Manager - next check for
240            # an Attribute Authority URI or instance running locally
241            if kw.get('attributeAuthorityURI') is None and \
242               kw.get('attributeAuthority') is None:
243                wsgiAttributeAuthorityClient = WSGIAttributeAuthorityClient(
244                                environ=self._environ,
245                                environKey=self._attributeAuthorityEnvironKey)
246
247                if wsgiAttributeAuthorityClient.refInEnviron:
248                    kw['attributeAuthority'] = wsgiAttributeAuthorityClient.ref
249                else:
250                    raise WSGISessionManagerClientConfigError(
251                        "No Attribute Authority URI or server object has been "
252                        "set and no reference is available in environ")
253                   
254            return self.ref.getAttCert(**kw)
255   
256        elif self._client is None:           
257            raise WSGISessionManagerClientConfigError("No reference to a "
258                        "local Session Manager is set and no SOAP client "
259                        "to a remote service has been initialized")
260        else:
261            # Filter out keywords which apply to a Session Manager local
262            # instance call
263            if 'username' in kw:
264                kw.pop('username')
265                log.warning('Trying call via SOAP interface: '
266                            'removing the "username" keyword '
267                            'ndg.security.common.sessionmanager.'
268                            'SessionManagerClient.getAttCert doesn\'t support '
269                            'this keyword')
270               
271            if 'refreshAttCert' in kw:
272                kw.pop('refreshAttCert')
273                log.warning('Trying call via SOAP interface: '
274                            'removing the "refreshAttCert" keyword '
275                            'ndg.security.common.sessionmanager.'
276                            'SessionManagerClient.getAttCert doesn\'t support '
277                            'this keyword')
278               
279            if 'attCertRefreshElapse' in kw:
280                kw.pop('attCertRefreshElapse')
281                log.warning('Trying call via SOAP interface: '
282                            'removing the "attCertRefreshElapse" keyword '
283                            'ndg.security.common.sessionmanager.'
284                            'SessionManagerClient.getAttCert doesn\'t support '
285                            'this keyword')
286
287            return self._client.getAttCert(**kw)
Note: See TracBrowser for help on using the repository browser.