Ignore:
Timestamp:
01/09/08 14:37:03 (13 years ago)
Author:
cbyrom
Message:

Create new utility module, ClassFactory? - to allow generic instantiation
of classes dynamically.

Implement use of this in the AttAuth? and SessionMgr? services + adjust
the config files for these accordingly + abstract use of MyProxy? in
SessionMgr? to generic authNService - and create packages with real
and test authN services. Adjust the SessionMgr? tests to use the
test authN service.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/SessionMgr/__init__.py

    r4144 r4158  
    1414 
    1515# Modify sys.path when carrying out dynamic import for Credential Repository 
    16 import sys 
     16import sys, os 
    1717 
    1818# Time module for use with cookie expiry 
     
    4444                                X509CertExpired, X509CertInvalidNotBeforeTime  
    4545 
    46 # MyProxy server interface 
    47 from ndg.security.server.MyProxy import * 
    48  
    4946# Use client package to allow redirection of authorisation requests and  
    5047# to retrieve Attribute Authority public key 
     
    5754from ndg.security.common.utils.ConfigFileParsers import readAndValidateProperties 
    5855 
     56# utility to instantiate classes dynamically 
     57from ndg.security.common.utils.ClassFactory import instantiateClass 
    5958# Use in SessionMgr __redirectAttCertReq to retrieve and store Public  
    6059# key 
     
    343342 
    344343    # valid configuration property keywords 
     344    WS_SETTINGS_KEY = 'WS-Security' 
     345    AUTHN_KEY_NAME = 'authNServiceProp' 
     346    CRED_REPOS_KEY_NAME = 'credReposProp' 
     347 
    345348    __validElem = \ 
    346349    { 
     
    353356        'sessMgrURI':             None, 
    354357        'cookieDomain':           None,  
    355         'myProxyProp':            None,  
    356         'credReposProp':          ('modFilePath', 'modName', 'className',  
     358        'authNServiceProp':        None,  
     359        CRED_REPOS_KEY_NAME:          ('modFilePath', 'modName', 'className',  
    357360                                   'propFile'), 
    358361        'simpleCACltProp':        ('uri', 'xmlSigKeyFile', 'xmlSigCertFile',  
     
    362365    __confDir = "conf" 
    363366    __propFileName = "sessionMgrProperties.xml" 
    364       
    365     WS_SETTINGS_KEY = 'WS-Security' 
    366367     
    367368    #_________________________________________________________________________ 
     
    390391        # setProperties/readProperties and then loadCredReposInterface 
    391392        self.__credRepos = None 
    392          
    393         # MyProxy interface 
    394         try: 
    395             self.__myPx = MyProxyClient() 
    396              
    397         except Exception, e: 
    398             raise SessionMgrError("Creating MyProxy interface: %s" % e) 
    399393     
    400394        # Set from input or use defaults based or environment variables 
     
    404398        self.readProperties() 
    405399 
     400        # Instantiate the authentication service to use with the session manager 
     401        self.__authNService = instantiateClass( 
     402                self.__prop[self.AUTHN_KEY_NAME].get('moduleName'),\ 
     403                self.__prop[self.AUTHN_KEY_NAME].get('className'),\ 
     404                moduleFilePath=self.__prop[self.AUTHN_KEY_NAME].get('moduleFilePath'),\ 
     405                objectType=AbstractAutheNService, \ 
     406                classProperties=self.__prop[self.AUTHN_KEY_NAME]) 
     407 
     408 
    406409        # Call here as we can safely expect that all Credential Repository 
    407410        # parameters have been set above 
    408         self.loadCredReposInterface() 
    409  
     411        self.__credRepos = instantiateClass( 
     412                self.__prop[self.CRED_REPOS_KEY_NAME].get('modName'),\ 
     413                self.__prop[self.CRED_REPOS_KEY_NAME].get('className'),\ 
     414                moduleFilePath=self.__prop[self.CRED_REPOS_KEY_NAME].get('modFilePath'),\ 
     415                objectType=CredRepos, \ 
     416                classProperties=self.__prop[self.CRED_REPOS_KEY_NAME]) 
     417         
    410418        # Set any properties that were provided by keyword input 
    411         # 
    412         # Nb. If any are duplicated with tags in the properties file they 
     419        # NB If any are duplicated with tags in the properties file they 
    413420        # will overwrite the latter 
    414         # 
    415         # loadCredReposInterface must be called explicitly if propFilePath 
    416         # wasn't set.  This is because if properties are passed by keyword  
    417         # alone there is no guarantee that those needed to load the interface 
    418         # will be present.  readProperties however, requires that all the 
    419         # required parameters are present in the properties file. 
    420421        self.setProperties(**prop) 
    421          
    422          
    423     #_________________________________________________________________________ 
    424     def loadCredReposInterface(self, credReposPPhrase=None, Force=False): 
    425         """ 
    426         Pick up and instantiate Credential Repository interface class from  
    427         properties file settings/keywords set by setProperties/__init__ 
    428          
    429         @type credReposPPhrase: string 
    430         @param credReposPPhrase: password for CredentialRepository database 
    431         This is passed into the Credential Repository object but may not 
    432         be needed.  e.g. the custom class could pick up a password from 
    433         the properties file for it - ['credRepos']['propFilePath'] 
    434          
    435         @type Force: boolean 
    436         @param Force: flag to force reload of Credential Repository instance 
    437         """ 
    438          
    439         log.debug("Loading Credential Repository interface ...") 
    440          
    441         # Don't bother if object has already been created.  Use Force=True 
    442         # to override and force reload 
    443         if Force is False and self.__credRepos is not None: 
    444             return 
    445          
    446         # Credentials repository - permanent store of user credentials 
    447         try: 
    448             try: 
    449                 # Module file path may be None if the new module to be loaded 
    450                 # can be found in the existing system path             
    451                 if self.__prop['credReposProp']['modFilePath'] is not None: 
    452                     # Temporarily extend system path ready for import 
    453                     sysPathBak = sys.path[:] 
    454  
    455                     if not os.path.exists(\ 
    456                               self.__prop['credReposProp']['modFilePath']): 
    457                         raise Exception, "File path '%s' doesn't exist" % \ 
    458                               self.__prop['credReposProp']['modFilePath'] 
    459                                
    460                     sys.path.append(\ 
    461                                 self.__prop['credReposProp']['modFilePath']) 
    462                  
    463                 # Import module name specified in properties file 
    464                 credReposMod = \ 
    465                     __import__(self.__prop['credReposProp']['modName'], 
    466                                globals(), 
    467                                locals(), 
    468                                [self.__prop['credReposProp']['className']]) 
    469      
    470                 credReposClass = eval(\ 
    471                 'credReposMod.' + self.__prop['credReposProp']['className']) 
    472             finally: 
    473                 try: 
    474                     sys.path[:] = sysPathBak 
    475                 except NameError: 
    476                     # sysPathBak may not have been defined 
    477                     pass 
    478                  
    479         except KeyError, e: 
    480             raise SessionMgrError('Missing %s element for credential ' 
    481                                   'repository module import' % str(e)) 
    482                          
    483         except Exception, e: 
    484             raise SessionMgrError('Importing credential repository module: %s'\ 
    485                                   % str(e)) 
    486  
    487         # Check class inherits from CredWallet.CredRepos abstract base class 
    488         if not issubclass(credReposClass, CredRepos): 
    489             raise SessionMgrError("Credential Repository class %s must be " 
    490                                   "inherited from %s" % \ 
    491                                   (credReposClass, CredRepos)) 
    492  
    493         # Instantiate custom class 
    494         try: 
    495             self.__credRepos = credReposClass(\ 
    496                       propFilePath=self.__prop['credReposProp']['propFile'], 
    497                       dbPPhrase=credReposPPhrase) 
    498              
    499         except Exception, e: 
    500             raise SessionMgrError( 
    501             "Error instantiating Credential Repository interface: " + str(e)) 
    502       
    503         log.info(\ 
    504 'Instantiated "%s" class from Credential Repository module: "%s" file path %s' % \ 
    505          (self.__prop['credReposProp']['className'], 
    506           self.__prop['credReposProp']['modName'], 
    507           self.__prop['credReposProp']['modFilePath'] or "from PYTHONPATH")) 
    508  
    509422         
    510423    #_________________________________________________________________________         
     
    624537                continue 
    625538             
    626             if key == 'myProxyProp': 
    627                 self.__myPx.setProperties(**val) 
    628                  
    629             elif key == 'credReposProp': 
     539            if key == self.CRED_REPOS_KEY_NAME: 
    630540                # Check for missing elements 
    631541                missingElem.extend(getMissingElem(\ 
    632                                            self.__validElem['credReposProp'], 
    633                                            self.__prop['credReposProp'])) 
     542                                           self.__validElem[self.CRED_REPOS_KEY_NAME], 
     543                                           self.__prop[self.CRED_REPOS_KEY_NAME])) 
    634544                     
    635545            elif key == 'simpleCACltProp': 
     
    640550                     
    641551 
    642         missingElem.extend(getMissingElem(self.__prop, self.__validElem)) 
     552        missingElem.extend(getMissingElem(self.__validElem, self.__prop)) 
    643553        errMsg = '' 
    644554         
     
    665575        for key, value in prop.items(): 
    666576                        
    667             if key == 'myProxyProp': 
    668                 self.__myPx.setProperties(prop[key]) 
    669      
    670             elif key == 'credReposProp': 
    671                 self.__prop['credReposProp'] = prop[key].copy() 
     577            if key == 'authNProp': 
     578                self.__authNService.setProperties(prop[key]) 
     579     
     580            elif key == self.CRED_REPOS_KEY_NAME: 
     581                self.__prop[self.CRED_REPOS_KEY_NAME] = prop[key].copy() 
    672582 
    673583            elif key in self.__validElem: 
     
    681591                raise SessionMgrError(\ 
    682592                    "Key \"%s\" is not a valid Session Manager property" % key) 
    683          
    684          
    685     #_________________________________________________________________________ 
    686     def addUser(self, username, passphrase=None):         
    687         """Register a new user with an NDG data centre 
    688          
    689         addUser([caConfigFilePath, ]|[, caPassPhrase] 
    690                 |[, userName=u, pPhrase=p]) 
    691  
    692         returns XML formatted response message 
    693          
    694         caConfigFilePath|caPassPhrase:  pass phrase for SimpleCA's 
    695                                         certificate.  Set via file or direct 
    696                                         string input respectively.  Set here 
    697                                         to override setting [if any] made at 
    698                                         object creation. 
    699          
    700                                         Passphrase is only required if 
    701                                         SimpleCA is instantiated on the local 
    702                                         machine.  If SimpleCA WS is called no 
    703                                         passphrase is required. 
    704                                          
    705         **kw:                      use as alternative to  
    706                                         reqXMLtxt keyword - pass in  
    707                                         username and pass-phrase for new user  
    708                                         unencrypted as keywords username 
    709                                         and pPhrase respectively.""" 
    710  
    711         log.debug("Calling SessionMgr.addUser ...") 
    712          
    713         # Ask CA to sign certificate 
    714          
    715         # Add new user certificate to MyProxy Repository 
    716         self.__myPx.store(username,  
    717                           certFile, 
    718                           keyFile, 
    719                           ownerCertFile=None, 
    720                           ownerKeyFile=None, 
    721                           ownerPassphrase=None, 
    722                           lifetime=None, 
    723                           force=True) 
    724  
    725         return userDN            
    726593     
    727594     
     
    833700                # Get a proxy certificate to represent users ID for the new 
    834701                # session 
    835                 userCreds = self.__myPx.logon(username, passphrase) 
     702                userCreds = self.__authNService.logon(username, passphrase) 
    836703                 
    837704                # unpack  
     
    902769                             *creds)       
    903770            except Exception, e: 
    904                 raise SessionMgrError("Creating User Session: %s" % e) 
     771                raise SessionMgrError( 
     772                        "Error occurred whilst creating User Session: %s" % e) 
    905773 
    906774            # Also allow access by user DN 
     
    12111079        log.debug("Calling SessionMgr.auditCredRepos ...") 
    12121080        self.__credRepos.auditCredentials() 
     1081 
     1082 
     1083class AbstractAutheNService: 
     1084    """ 
     1085    An abstract base class to define the authentication service interface for use 
     1086    with a SessionMgr service 
     1087    """ 
     1088 
     1089    # valid configuration property keywords 
     1090    __validKeys = ('hostname', 
     1091                   'port', 
     1092                   'serverDN', 
     1093                   'serverCNprefix', 
     1094                   'gridSecurityDir', 
     1095                   'openSSLConfFilePath', 
     1096                   'tmpDir', 
     1097                   'proxyCertMaxLifetime', 
     1098                   'proxyCertLifetime', 
     1099                   'caCertFile') 
     1100 
     1101    def __init__(self, propFilePath=None, **prop): 
     1102        """Make an initial settings for client connections to MyProxy 
     1103         
     1104        Settings are held in a dictionary which can be set from **prop, 
     1105        a call to setProperties() or by passing settings in an XML file 
     1106        given by propFilePath 
     1107         
     1108        @param propFilePath:   set properties via a configuration file 
     1109        @param **prop:         set properties via keywords - see __validKeys 
     1110        class variable for a list of these 
     1111        """ 
     1112        pass 
     1113 
     1114 
     1115    def setProperties(self, **prop): 
     1116        """Update existing properties from an input dictionary 
     1117        Check input keys are valid names""" 
     1118        raise NotImplementedError, \ 
     1119            self.getRoles.__doc__.replace('\n       ','') 
     1120 
     1121 
     1122    def logon(self, username, passphrase, lifetime=None): 
     1123        """ 
     1124        Retrieve a proxy credential from a proxy server 
     1125         
     1126        @type username: basestring 
     1127        @param username: username of credential 
     1128         
     1129        @type passphrase: basestring 
     1130        @param passphrase: pass-phrase for private key of credential held on 
     1131        server 
     1132         
     1133        @type lifetime: int 
     1134        @param lifetime: lifetime for generated certificate 
     1135         
     1136        @raise GetError: 
     1137        @raise RetrieveError: 
     1138        @rtype: tuple 
     1139        @return credentials as strings in PEM format: the 
     1140        user certificate, its private key and the issuing certificate.  The 
     1141        issuing certificate is only set if the user certificate is a proxy 
     1142        """ 
     1143        raise NotImplementedError, \ 
     1144            self.getRoles.__doc__.replace('\n       ','') 
     1145             
Note: See TracChangeset for help on using the changeset viewer.