source: TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/authninterface/basic.py @ 5452

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/authninterface/basic.py@5452
Revision 5452, 7.3 KB checked in by pjkersha, 11 years ago (diff)
Line 
1"""NDG Security Basic OpenID Authentication Interface.
2
3A demonstration implementation of an authentication interface for
4OpenIDProviderMiddleware WSGI.  Username/password and OpenId user identifier
5details are read from a config file and passed as keywords.  This class is not
6intended for production use.
7
8NERC DataGrid Project
9
10"""
11__author__ = "P J Kershaw"
12__date__ = "01/08/08"
13__copyright__ = "(C) 2009 Science and Technology Facilities Council"
14__contact__ = "Philip.Kershaw@stfc.ac.uk"
15__revision__ = "$Id$"
16import logging
17log = logging.getLogger(__name__)
18
19from ndg.security.server.wsgi.openid.provider import AbstractAuthNInterface, \
20    AuthNInterfaceInvalidCredentials, AuthNInterfaceRetrieveError, \
21    AuthNInterfaceConfigError, AuthNInterfaceUsername2IdentifierMismatch
22 
23   
24class BasicAuthNInterface(AbstractAuthNInterface):
25    '''Basic Authentication interface class for OpenIDProviderMiddleware
26   
27    it uses username/password details retrieved from config file / keyword
28    entry.  This class is for testing only.  NOT for production use'''
29   
30    propertyKeyNames = ('userCreds', 'username2UserIdentifiers')
31   
32    def __init__(self, **prop):
33        """Make any initial settings
34       
35        Settings are held in a dictionary which can be set from **prop,
36        a call to setProperties() or by passing settings in an XML file
37        given by propFilePath
38       
39        @type **prop: dict
40        @param **prop: set properties via keywords
41        @raise AuthNInterfaceConfigError: error with configuration
42        """
43        # Test/Admin username/password set from ini/kw args
44        userCredsField = prop.get('userCreds')
45        if not userCredsField:
46            raise AuthNInterfaceConfigError('No "userCreds" config option '
47                                            "found")
48        self._userCreds = {}
49        for userEntry in userCredsField.split(): 
50            # Split username, password and OpenID name list 
51            userCreds = userEntry.strip().split(':')
52           
53            # Split OpenID name list
54            userCreds[-1] = tuple(userCreds[-1].split(','))
55           
56            # Convert into a dictionary indexed by username
57            userCredsKeys = ('password', 'identifiers')
58            self._userCreds[userCreds[0]] = dict(zip(userCredsKeys, 
59                                                     userCreds[1:])) 
60   
61    def logon(self, environ, userIdentifier, username, password):
62        """Interface login method
63       
64        @type environ: dict
65        @param environ: standard WSGI environ parameter
66
67        @type username: basestring
68        @param username: user identifier
69       
70        @type password: basestring
71        @param password: corresponding password for username givens
72       
73        @raise AuthNInterfaceInvalidCredentials: invalid username/password
74        @raise AuthNInterfaceUsername2IdentifierMismatch: no OpenID matching
75        the given username
76        """
77        if self._userCreds.get(username, {}).get('password') != password:
78            raise AuthNInterfaceInvalidCredentials()
79       
80        if userIdentifier is not None and \
81           userIdentifier not in self._userCreds[username]['identifiers']:
82            raise AuthNInterfaceUsername2IdentifierMismatch()
83
84    def logout(self):
85        pass
86       
87    def username2UserIdentifiers(self, environ, username):
88        """Map the login username to an identifier which will become the
89        unique path suffix to the user's OpenID identifier.  The
90        OpenIDProviderMiddleware takes self.urls['id_url'] and adds it to this
91        identifier:
92       
93            identifier = self._authN.username2UserIdentifiers(environ,username)
94            identityURL = self.urls['url_id'] + '/' + identifier
95       
96        @type environ: dict
97        @param environ: standard WSGI environ parameter
98
99        @type username: basestring
100        @param username: user identifier
101       
102        @rtype: tuple
103        @return: identifiers to be used to make OpenID user identity URLs.
104       
105        @raise AuthNInterfaceRetrieveError: error with retrieval of information
106        to identifier e.g. error with database look-up.
107        """
108        try:
109            return self._userCreds[username]['identifiers']
110        except KeyError:
111            raise AuthNInterfaceRetrieveError('No entries for "%s" user' % 
112                                              username)
113
114
115from ndg.security.server.wsgi.utils.sessionmanagerclient import \
116    WSGISessionManagerClient, AuthNServiceInvalidCredentials
117   
118class BasicSessionManagerOpenIDAuthNInterface(BasicAuthNInterface):
119    '''Authentication interface class for OpenIDProviderMiddleware to enable
120    authentication to a Session Manager instance running in the same WSGI
121    stack or via a SOAP call to a remote service.  This is a basic test
122    interface.  See sessionmanager module for a full implementation linking to
123    a database via SQLAlchemy
124    '''
125   
126    def __init__(self, **prop):
127        """Extends BasicAuthNInterface initialising Session Manager Client
128       
129        @type **prop: dict
130        @param **prop: set properties via keywords
131        @raise AuthNInterfaceConfigError: error with configuration
132        """
133        user2Identifier = prop.pop('username2UserIdentifiers')
134        if user2Identifier:
135            self._username2Identifier = {}
136            for i in user2Identifier.split():
137                username, identifierStr = i.strip().split(':')
138                identifiers = tuple(identifierStr.split(','))
139                self._username2Identifier[username] = identifiers
140        else:
141            raise AuthNInterfaceConfigError('No "user2Identifier" config '
142                                            'option found')
143
144        self._client = WSGISessionManagerClient(**prop)
145       
146        # This is set at login
147        self.sessionId = None
148       
149    def logon(self, environ, userIdentifier, username, password):
150        """Interface login method
151       
152        @type environ: dict
153        @param environ: standard WSGI environ parameter
154       
155        @type username: basestring
156        @param username: user identifier
157       
158        @type password: basestring
159        @param password: corresponding password for username givens
160       
161        @raise AuthNInterfaceUsername2IdentifierMismatch: no OpenID
162        identifiers match the given username
163        @raise AuthNInterfaceInvalidCredentials: invalid username/password
164        """       
165        if userIdentifier is not None and \
166           userIdentifier not in self._username2Identifier.get(username):
167            raise AuthNInterfaceUsername2IdentifierMismatch()
168       
169        try:
170            self._client.environ = environ
171            connectResp = self._client.connect(username, passphrase=password)
172            self.sessionId = connectResp[-1]
173            log.debug("Connected to Session Manager with session ID: %s", 
174                      self.sessionId)
175
176        except AuthNServiceInvalidCredentials, e:
177            log.exception(e)
178            raise AuthNInterfaceInvalidCredentials()
179
180    def logout(self):
181        """logout from the Session Manager
182        """
183        try:
184            self._client.disconnect(sessID=self.sessionId)
185           
186        except Exception, e:
187            log.exception(e)
188            raise AuthNInterfaceInvalidCredentials()
Note: See TracBrowser for help on using the repository browser.