source: TI12-security/trunk/python/NDG/AttAuthority.py @ 674

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/NDG/AttAuthority.py@674
Revision 674, 28.6 KB checked in by pjkersha, 14 years ago (diff)

* Working version for mapped certificates *

ndgSessionClient.py:

  • renamed dict to argDict to avoid clash with existing arg var.
  • added code for handling ext attCert list and trusted host list files.
  • Changed so that --connect and --req-autho can be specified together so that a connect call is

concatenated with a call to request authorisation.

attAuthorityIOtest.py: unit tests for AttAuthorityIO classes.
attCertTest.py: unit tests for AttCert?.

AttAuthorityIO.py:

attAuthority_services_server.py: update and fixes to GetTrustedHostInfo? WS stub.

AttAuthority?.py:

AttCert?.py: !! important fix - added nonzero method so that test on AttCert? instance
yields True e.g. if attCert: ...

Session.py:

  • SessionMgr?.readProperties - only strip white space from XML data if it's string type -

elementtree sets content to None if an empty tag is present in the XML it's reading.

CredWallet?.py: changes to WS calls - use AttAuthorityIO classes - AuthorisationReq/?
AuthorisationResp? + TrustedHostInfoReq/TrustedHostInfoResp?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1"""NDG Attribute Authority handles security authentication and authorization
2
3NERC Data Grid Project
4
5P J Kershaw 15/04/05
6
7Copyright (C) 2005 CCLRC & NERC
8
9This software may be distributed under the terms of the Q Public License,
10version 1.0 or later.
11"""
12
13cvsID = '$Id$'
14
15import types
16
17
18# Create unique names for attribute certificates
19import tempfile
20import os
21
22# Alter system path for dynamic import of user roles class
23import sys
24
25# For parsing of properties file
26import cElementTree as ElementTree
27
28# X509 Certificate handling
29from X509 import *
30
31# NDG Attribute Certificate
32from AttCert import *
33
34# Format for XML messages passed over WS
35from AttAuthorityIO import *
36
37
38#_____________________________________________________________________________
39class AttAuthorityError(Exception):
40    """Exception handling for NDG Attribute Authority class."""
41   
42    def __init__(self, msg):
43        self.__msg = msg
44         
45    def __str__(self):
46        return self.__msg
47
48
49
50
51#_____________________________________________________________________________
52class AttAuthorityAccessDenied(AttAuthorityError):
53    """NDG Attribute Authority - access denied exception.
54
55    Raise from authorise method where no roles are available for the user
56    but that the request is otherwise valid.  In all other error cases raise
57    AttAuthorityError"""   
58    pass
59
60
61
62#_____________________________________________________________________________
63class AttAuthority:
64
65    """NDG Attribute Authority - server for user authentication/authorization.
66    """
67
68    # Code designed from NERC Data Grid Enterprise and Information Viewpoint
69    # documents.
70    #
71    # Also, draws from Neil Bennett's ACServer class used in the Java
72    # implementation of NDG Security
73
74    # valid configuration property keywords
75    __validKeys = [ 'name',
76                    'keyFile',
77                    'keyPwd',
78                    'certFile',
79                    'caCertFile',
80                    'attCertLifeTime',
81                    'attCertNotBeforeOff',
82                    'attCertFilePfx',
83                    'attCertFileSfx',
84                    'mapConfigFile',
85                    'attCertDir',
86                    'dnSeparator',
87                    'usrRolesModFilePath',
88                    'usrRolesModName',
89                    'usrRolesClassName',
90                    'usrRolesPropFile']
91   
92    def __init__(self, propFilePath, bReadMapConfig=True):
93        """Create new NDG Attribute Authority instance
94
95        propFilePath:   path to file containing Attribute Authority
96                        configuration parameters.
97        bReadMapConfig: by default the Map Configuration file is read.  Set
98                        this flag to False to override.
99        """
100       
101        if not isinstance(propFilePath, basestring):
102            raise AttAuthorityError("Input Properties file path " + \
103                                    "must be a valid string.")
104
105
106        # Initialise role mapping look-ups - These are set in readMapConfig()
107        self.__mapConfig = None
108        self.__localRole2Trusted = None
109        self.__trusted2LocalRole = None
110
111
112        # Configuration file properties are held together in a dictionary
113        self.__prop = {}
114
115        # Read Attribute Authority Properties file
116        self.readProperties(propFilePath)
117
118        # Read the Map Configuration file
119        if bReadMapConfig:
120            self.readMapConfig()
121
122        # Instantiate Certificate object
123        self.__cert = X509Cert(self.__prop['certFile'])
124        self.__cert.read()
125
126        # Check it's valid
127        if not self.__cert.isValidTime():
128            raise AttAuthorityError(\
129                "Attribute Authority's certificate has expired!")
130       
131        # Check CA certificate
132        caCert = X509Cert(self.__prop['caCertFile'])
133        caCert.read()
134       
135        if not caCert.isValidTime():
136            raise AttAuthorityError("CA certificate has expired!")
137
138       
139        # Issuer details - serialise using the separator string set in the
140        # properties file
141        self.__issuer = \
142            self.__cert.dn.serialise(separator=self.__prop['dnSeparator'])
143
144        self.__issuerSerialNumber = self.__cert.serialNumber
145
146       
147        # Set-up user roles interface
148        try:
149            # Temporarily extend system path ready for import
150            sysPathBak = sys.path
151            sys.path.append(self.__prop['usrRolesModFilePath'])
152           
153            # Import module name specified in properties file
154            usrRolesMod = __import__(self.__prop['usrRolesModName'],
155                                     globals(),
156                                     locals(),
157                                     [self.__prop['usrRolesClassName']])
158
159            sys.path = sysPathBak
160           
161            usrRolesClass = eval('usrRolesMod.' + \
162                                 self.__prop['usrRolesClassName'])
163
164        except Exception, e:
165            raise AttAuthorityError('Importing User Roles module: %s' % e)
166
167        # Check class inherits from AAUserRoles abstract base class
168        if not issubclass(usrRolesClass, AAUserRoles):
169            raise AttAuthorityError(\
170                "User Roles class %s must be derived from AAUserRoles" % \
171                self.__prop['usrRolesClassName'])
172
173
174        # Instantiate custom class
175        try:
176            self.__usrRoles = usrRolesClass(self.__prop['usrRolesPropFile'])
177           
178        except Exception, e:
179            raise AttAuthorityError(\
180                "Error instantiating User Roles interface: " + str(e))
181
182       
183    #_________________________________________________________________________
184    def authorise(self,
185                  reqXMLtxt=None, 
186                  proxyCertFilePath=None,
187                  userAttCertFilePath=None,
188                  **reqKeys):
189
190        """Request a new Attribute Certificate for authorisation
191
192        reqXMLtxt:              input keywords as tags in formatted XML string
193                                String must follow format for
194                                AttAuthorityIO.AuthorisationReq class to
195                                parse.
196                               
197        proxyCertFilePath|proxyCert:
198
199                                user's proxy certificate use appropriate
200                                keyword for input as a file path or as the
201                                text content respectively.
202                               
203                                Nb. proxyCert is set via reqKeys
204                               
205        userAttCertFilePath|userAttCert:
206       
207                                externally provided attribute certificate
208                                from another data centre.  This is only
209                                necessary if the user is not registered with
210                                this attribute authority.
211
212                                Pass in either the file path or a string
213                                containing the certificate XML content.
214                               
215                                Nb. userAttCert is set via reqKeys
216                                """
217
218        if reqXMLtxt is not None:
219            # Parse XML text into keywords corresponding to the input
220            # parameters
221            if not isinstance(reqXMLtxt, basestring):
222                raise AttAuthorityError(\
223                            "XML Authorisation request must be a string")
224                                       
225            # Parse and decrypt as necessary
226            try:
227                # 1st assume that the request was encrypted
228                reqKeys = AuthorisationReq(encrXMLtxt=reqXMLtxt,
229                                    encrPriKeyFilePath=self.__prop['keyFile'],
230                                    encrPriKeyPwd=self.__prop['keyPwd'])
231            except Exception, e:
232               
233                # Error occured decrypting - Trying parsing again, but this
234                # time assuming non-encrypted
235                try:
236                    reqKeys = AuthorisationReq(xmlTxt=reqXMLtxt)
237                   
238                except Exception, e:
239                    raise AttAuthorityError(\
240                        "Error parsing authorisation request: %s" % e)
241
242
243        # Read proxy certificate
244        try:
245            usrProxyCert = X509Cert()
246           
247            if proxyCertFilePath is not None and \
248               isinstance(proxyCertFilePath, basestring):
249
250                # Proxy Certificate input as a file
251                usrProxyCert.read(proxyCertFilePath)
252               
253            elif reqKeys['proxyCert'] is not None:
254
255                # Proxy Certificate input as string text
256                usrProxyCert.parse(reqKeys['proxyCert'])
257
258            else:
259                raise AttAuthorityError(\
260                    "no input proxy certificate file path or file text")
261           
262        except Exception, e:
263            raise AttAuthorityError("User Proxy Certificate: %s" % e)
264
265
266        # Check proxy certificate hasn't expired
267        if not usrProxyCert.isValidTime():
268            raise AttAuthorityError("User Proxy Certificate has expired")
269
270           
271        # Get Distinguished name from certificate as an X500DN type
272        usrDN = usrProxyCert.dn
273       
274       
275        # Make a new Attribute Certificate instance passing in certificate
276        # details for later signing
277        #
278        # Nb. new attribute certificate file path is created from the
279        # Credentials Repository
280        certFilePathList = [self.__prop['certFile'],self.__prop['caCertFile']]
281        attCert = AttCert(self.__newAttCertFilePath(),
282                          signingKeyFilePath=self.__prop['keyFile'],
283                          certFilePathList=certFilePathList)
284
285
286        # Set holder's (user's) Distinguished Name
287        try:
288            attCert['holder'] = \
289                        usrDN.serialise(separator=self.__prop['dnSeparator'])
290           
291        except Exception, e:
292            raise AttAuthorityError("User DN: %s" % e)
293
294       
295        # Set Issuer details from Attribute Authority
296        issuerDN = self.__cert.dn
297        try:
298            attCert['issuer'] = \
299                    issuerDN.serialise(separator=self.__prop['dnSeparator'])
300           
301        except Exception, e:
302            raise AttAuthorityError("Issuer DN: %s" % e)
303       
304        attCert['issuerName'] = self.__prop['name']
305        attCert['issuerSerialNumber'] = self.__issuerSerialNumber
306
307
308        # Set validity time
309        try:
310            attCert.setValidityTime(\
311                        lifeTime=self.__prop['attCertLifeTime'],
312                        notBeforeOffset=self.__prop['attCertNotBeforeOff'])
313
314            # Check against the proxy certificate's expiry
315            dtUsrProxyNotAfter = usrProxyCert.notAfter
316           
317            if attCert.getValidityNotAfter(asDatetime=True) > \
318               dtUsrProxyNotAfter:
319
320                # Adjust the attribute certificate's expiry date time
321                # so that it agrees with that of the proxy certificate
322                attCert.setValidityTime(dtNotAfter=dtUsrProxyNotAfter)
323           
324        except Exception, e:
325            raise AttAuthorityError("Error setting validity time: %s" % e)
326       
327
328        # Check name is registered with this Attribute Authority - if no
329        # user roles are found, the user is not registered
330        usrRoles = self.getRoles(str(usrDN))
331        if usrRoles:           
332            # Set as an Original Certificate
333            #
334            # User roles found - user is registered with this data centre
335            # Add roles for this user for this data centre
336            attCert.addRoles(usrRoles)
337
338            # Mark new Attribute Certificate as an original
339            attCert['provenance'] = 'original'
340
341        else:           
342            # Set as a Mapped Certificate
343            #
344            # No roles found - user is not registered with this data centre
345            # Check for an externally provided certificate from another
346            # trusted data centre
347            if userAttCertFilePath:
348               
349                # Read externally provided certificate
350                try:
351                    extAttCert = AttCertRead(userAttCertFilePath)
352                   
353                except Exception, e:
354                    raise AttAuthorityError(\
355                            "Reading external Attribute Certificate: %s" + e)
356                               
357            elif 'userAttCert' in reqKeys and reqKeys['userAttCert']:
358                extAttCert = reqKeys['userAttCert']
359               
360            else:
361                raise AttAuthorityAccessDenied(\
362                    "User \"%s\" is not registered " % attCert['holder'] + \
363                    "and no external attribute certificate is available " + \
364                    "to make a mapping.")
365
366
367            # Check it's an original certificate - mapped certificates can't
368            # be used to make further mappings
369            if extAttCert.isMapped():
370                raise AttAuthorityError(\
371                    "External Attribute Certificate must have an " + \
372                    "original provenance in order to make further mappings.")
373
374
375            # Check it's valid and signed
376            try:
377                # Give path to CA cert to allow check
378                extAttCert.isValid(raiseExcep=True,
379                                   certFilePathList=self.__prop['caCertFile'])
380               
381            except Exception, e:
382                raise AttAuthorityError(\
383                            "Invalid Remote Attribute Certificate: %s" + e)       
384
385
386            # Check that's it's holder matches the user certificate DN
387            try:
388                holderDN = X500DN(dn=extAttCert['holder'])
389               
390            except Exception, e:
391                raise AttAuthorityError(\
392                    "Error creating X500DN for holder: %s" + e)
393           
394            if holderDN != usrDN:
395                raise AttAuthorityError(\
396                    "User certificate and Attribute Certificate DNs " + \
397                    "don't match: " + str(usrDN) + " and " + str(holderDN))
398           
399 
400            # Get roles from external Attribute Certificate
401            trustedHostRoles = extAttCert.getRoles()
402
403
404            # Map external roles to local ones
405            localRoles = self.mapTrusted2LocalRoles(extAttCert['issuerName'],
406                                                    trustedHostRoles)
407            if not localRoles:
408                raise AttAuthorityAccessDenied(\
409                    "No local roles mapped to the %s roles: %s" % \
410                    (extAttCert['issuerName'], str(trustedHostRoles)))
411
412            attCert.addRoles(localRoles)
413           
414           
415            # Mark new Attribute Certificate as mapped
416            attCert['provenance'] = 'mapped'
417
418            # End set mapped certificate block
419           
420
421        try:
422            # Digitally sign certificate using Attribute Authority's
423            # certificate and private key
424            attCert.sign(signingKeyPwd=self.__prop['keyPwd'])
425           
426            # Check the certificate is valid
427            attCert.isValid(raiseExcep=True)
428           
429            # Write out certificate to keep a record of it for auditing
430            attCert.write()
431
432            # Return the cert to caller
433            return attCert
434       
435        except Exception, e:
436            raise AttAuthorityError("New Attribute Certificate \"%s\": %s" % \
437                                    (attCert.filePath, e))
438
439   
440
441
442    def readProperties(self, propFilePath=None):
443
444        """Read the configuration properties for the Attribute Authority
445
446        propFilePath: file path to properties file
447        """
448       
449        if propFilePath is not None:
450            if not isinstance(propFilePath, basestring):
451                raise AttAuthorityError("Input Properties file path " + \
452                                        "must be a valid string.")
453           
454            self.__propFilePath = propFilePath
455
456
457        try:
458            tree = ElementTree.parse(self.__propFilePath)
459           
460        except IOError, ioErr:
461            raise AttAuthorityError(\
462                                "Error parsing properties file \"%s\": %s" % \
463                                (ioErr.filename, ioErr.strerror))
464
465       
466        aaProp = tree.getroot()
467
468        # Copy properties from file as member variables
469        prop = dict([(elem.tag, elem.text) for elem in aaProp])
470
471
472        # Check for missing properties
473        propKeys = prop.keys()
474        missingKeys = [key for key in AttAuthority.__validKeys \
475                       if key not in propKeys]
476        if missingKeys != []:
477            raise AttAuthorityError("The following properties are " + \
478                                    "missing from the properties file: " + \
479                                    ', '.join(missingKeys))
480
481        # Strip white space - apart from fields where may be required
482        for key in prop:
483            if key != 'keyPwd' and prop[key]: 
484                prop[key] = prop[key].strip()
485               
486            # Check for environment variables in file paths
487            tagCaps = key.upper()
488            if 'FILE' in tagCaps or 'PATH' in tagCaps or 'DIR' in tagCaps:
489                prop[key] = os.path.expandvars(prop[key])
490 
491 
492        # Ensure Certificate time parameters are converted to numeric type
493        prop['attCertLifeTime'] = float(prop['attCertLifeTime'])
494        prop['attCertNotBeforeOff'] = float(prop['attCertNotBeforeOff'])
495         
496        self.__prop = prop
497
498       
499        # Check directory path
500        try:
501            dirList = os.listdir(self.__prop['attCertDir'])
502
503        except OSError, osError:
504            raise AttAuthorityError(\
505                "Invalid directory path Attribute Certificates store: " + \
506                osError.strerror)
507
508       
509       
510       
511    def readMapConfig(self, mapConfigFilePath=None):
512        """Parse Map Configuration file.
513
514        mapConfigFilePath:  file path for map configuration file.  If omitted,
515                            use member variable __mapConfigFilePath.
516        """
517       
518        if mapConfigFilePath is not None:
519            if not isinstance(mapConfigFilePath, basestring):
520                raise AttAuthorityError("Input Map Configuration file path "+\
521                                        "must be a valid string.")
522           
523            self.__prop['mapConfigFile'] = mapConfigFilePath
524
525       
526        tree = ElementTree.parse(self.__prop['mapConfigFile'])
527        rootElem = tree.getroot()
528
529        trustedElem = rootElem.findall('trusted')
530
531        # Dictionaries:
532        # 1) to hold all the data
533        self.__mapConfig = {}
534
535        # ... look-up
536        # 2) hosts corresponding to a given role and
537        # 3) roles of external data centre to this data centre
538        self.__localRole2TrustedHost = {}
539        self.__localRole2Trusted = {}
540        self.__trusted2LocalRole = {}
541       
542        for elem in trustedElem:
543
544            roleElem = elem.findall('role')
545            if not roleElem:
546                raise AttAuthorityError("\"role\" tag not found in \"%s\"" % \
547                                        self.__prop['mapConfigFile'])
548
549            try:
550                trustedHost = elem.attrib.values()[0]
551               
552            except Exception, e:
553                raise AttAuthorityError(\
554                                    "Error setting trusted host name: %s" % e)
555
556           
557            # Add signatureFile and list of roles
558            self.__mapConfig[trustedHost] = \
559            {
560                'wsdl': elem.findtext('wsdl'),
561                'role': [dict(i.items()) for i in roleElem]
562            }
563
564                   
565            self.__localRole2Trusted[trustedHost] = {}
566            self.__trusted2LocalRole[trustedHost] = {}
567           
568            for role in self.__mapConfig[trustedHost]['role']:
569
570                localRole = role['local']
571                remoteRole = role['remote']
572               
573                # Role to host look-up
574                if localRole in self.__localRole2TrustedHost:
575                   
576                    if trustedHost not in \
577                       self.__localRole2TrustedHost[localRole]:
578                        self.__localRole2TrustedHost[localRole].\
579                                                        append(trustedHost)                       
580                else:
581                    self.__localRole2TrustedHost[localRole] = [trustedHost]
582
583
584                # Trusted Host to local role and trusted host to trusted role
585                # map look-ups
586                try:
587                    self.__trusted2LocalRole[trustedHost][remoteRole].append(\
588                                                                localRole)                 
589                except KeyError:
590                    self.__trusted2LocalRole[trustedHost][remoteRole] = \
591                                                                [localRole]
592                   
593                try:
594                    self.__localRole2Trusted[trustedHost][localRole].append(\
595                                                                remoteRole)                 
596                except KeyError:
597                    self.__localRole2Trusted[trustedHost][localRole] = \
598                                                                [remoteRole]                 
599 
600
601           
602    def usrIsRegistered(self, usrDN):
603        """Check a particular user is registered with the Data Centre that the
604        Attribute Authority represents"""
605        return self.__usrRoles.usrIsRegistered(usrDN)
606       
607
608
609
610
611    def getRoles(self, dn):
612        """Get the roles available to the registered user identified usrDN.
613        """
614
615        # Call to AAUserRoles derived class.  Each Attribute Authority
616        # should define it's own roles class derived from AAUserRoles to
617        # define how roles are accessed
618        try:
619            return self.__usrRoles.getRoles(dn)
620
621        except Exception, e:
622            raise AttAuthorityError("Getting user roles: %s" % e)
623
624
625
626   
627    def getTrustedHostInfo(self, reqXMLtxt=None, **reqKeys):
628        """Return a dictionary of the hosts that have trust relationships
629        with this AA.  The dictionary is indexed by the trusted host name
630        and contains WSDL URIs and the roles that map to the
631        given input local role.
632
633        If no role is input, return all the AA's trusted hosts with all
634        their possible roles
635
636        Returns None if role isn't recognised
637       
638        reqXMLtxt:              input keywords as tags in formatted XML string
639                                String must follow format for
640                                AttAuthorityIO.TrustedHostInfoReq class to
641                                parse.
642                                """
643
644        if reqXMLtxt is not None:
645            # Parse XML text into keywords corresponding to the input
646            # parameters
647            if not isinstance(reqXMLtxt, basestring):
648                raise AttAuthorityError(\
649                            "XML Authorisation request must be a string")
650                                       
651            # Parse and decrypt as necessary
652            try:
653                # 1st assume that the request was encrypted
654                reqKeys = TrustedHostInfoReq(encrXMLtxt=reqXMLtxt,
655                                    encrPriKeyFilePath=self.__prop['keyFile'],
656                                    encrPriKeyPwd=self.__prop['keyPwd'])
657            except Exception, e:
658               
659                # Error occured decrypting - Trying parsing again, but this
660                # time assuming non-encrypted
661                try:
662                    reqKeys = TrustedHostInfoReq(xmlTxt=reqXMLtxt)
663                   
664                except Exception, e:
665                    raise AttAuthorityError(\
666                        "Error parsing authorisation request: %s" % e)
667                                         
668                                         
669        if not self.__localRole2Trusted:
670            raise AttAuthorityError("Roles to host look-up is not set - " + \
671                                    "ensure readMapConfig() has been called.")
672
673
674        if 'role' not in reqKeys:
675            # No role input - return all trusted hosts with their WSDL URIs
676            # and roles
677            trustedHostInfo = dict([\
678               (k, \
679                {'wsdl': v['wsdl'], \
680                 'role': [role['remote'] for role in v['role']]}) \
681                for k, v in self.__mapConfig.items()])
682        else:           
683            # Get trusted hosts for given input local role       
684            try:
685                trustedHosts = self.__localRole2TrustedHost[reqKeys['role']]
686            except:
687                return None
688   
689   
690            # Get associated WSDL URI and roles for the trusted hosts
691            # identified and return as a dictionary indexed by host name
692            trustedHostInfo = dict([(host, \
693                {'wsdl': self.__mapConfig[host]['wsdl'], \
694                 'role': self.__localRole2Trusted[host][reqKeys['role']]}) \
695                 for host in trustedHosts])
696                         
697        return trustedHostInfo
698
699
700
701
702    def mapTrusted2LocalRoles(self, trustedHost, trustedHostRoles):
703        """Map roles of trusted hosts to roles for this data centre
704
705        trustedHost:        name of external trusted data centre
706        trustedHostRoles:   list of external roles to map"""
707
708        if not self.__trusted2LocalRole:
709            raise AttAuthorityError("Roles map is not set - ensure " + \
710                                    "readMapConfig() has been called.")
711
712
713        # Check the host name is a trusted one recorded in the map
714        # configuration
715        if not self.__trusted2LocalRole.has_key(trustedHost):
716            return []
717
718        # Add local roles, skipping if no mapping is found
719        localRoles = []
720        for trustedRole in trustedHostRoles:
721            if trustedRole in self.__trusted2LocalRole[trustedHost]:
722                localRoles.extend(\
723                        self.__trusted2LocalRole[trustedHost][trustedRole])
724               
725        return localRoles
726
727
728
729
730    def __newAttCertFilePath(self):
731        """Create a new unique attribute certificate file path"""
732       
733        attCertFd, attCertFilePath = \
734                   tempfile.mkstemp(suffix=self.__prop['attCertFileSfx'],
735                                    prefix=self.__prop['attCertFilePfx'],
736                                    dir=self.__prop['attCertDir'],
737                                    text=True)
738
739        # The file is opened - close using the file descriptor returned in the
740        # first element of the tuple
741        os.close(attCertFd)
742
743        # The file path is the 2nd element
744        return attCertFilePath
745
746
747
748
749#_____________________________________________________________________________
750class AAUserRolesError(Exception):
751
752    """Exception handling for NDG Attribute Authority User Roles interface
753    class."""
754   
755    def __init__(self, msg):
756        self.__msg = msg
757         
758    def __str__(self):
759        return self.__msg
760
761
762
763#_____________________________________________________________________________
764class AAUserRoles:
765
766    """An abstract base class to define the user roles interface to an
767    Attribute Authority.
768
769    Each NDG data centre should implement a derived class which implements
770    the way user roles are provided to its representative Attribute Authority.
771   
772    Roles are expected to indexed by user Distinguished Name (DN).  They
773    could be stored in a database or file."""
774
775    # User defined class may wish to specify a URI for a database interface or
776    # path for a user roles configuration file
777    def __init__(self, dbURI=None, filePath=None):
778        """User Roles abstract base class - derive from this class to define
779        roles interface to Attribute Authority"""
780        raise NotImplementedError(\
781            self.__init__.__doc__.replace('\n       ',''))
782
783
784    def usrIsRegistered(self, dn):
785        """Derived method should return True if user is known otherwise
786        False"""
787        raise NotImplementedError(
788            self.UserIsRegistered.__doc__.replace('\n       ',''))
789
790
791    def getRoles(self, dn):
792        """Derived method should return the roles for the given user's
793        DN or else raise an exception"""
794        raise NotImplementedError(
795            self.getRoles.__doc__.replace('\n       ',''))
796
797
798#_____________________________________________________________________________
799# Test routines
800def testGetTrustedHostInfo(role=None,
801                           propFilePath='./attAuthorityProperties.xml'):
802    "Test getTrustedHosts AttAuthority method"
803    import pdb
804    pdb.set_trace()
805   
806    try:
807        aa = AttAuthority(propFilePath)
808        return aa.getTrustedHostInfo(role)
809   
810    except Exception, e:
811        print e
Note: See TracBrowser for help on using the repository browser.