Ignore:
Timestamp:
24/08/10 16:39:39 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 2: XACML-Security Integration

  • simplified credential wallet - now a single class SAMLAssertionWallet for caching assertions containing authorisation decision statements and/or attribute statements
File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/credentialwallet.py

    r7358 r7359  
    306306            setattr(self, optName, val) 
    307307          
    308     def addCredentials(self, key, credentials, verifyCredentials=True): 
     308    def addCredentials(self, key, assertions, verifyCredentials=True): 
    309309        """Add a new assertion to the list of assertion credentials held. 
    310310 
    311         @type credentials: iterable 
    312         @param credential: list of SAML assertions for a given issuer 
     311        @type assertions: iterable 
     312        @param assertions: list of SAML assertions for a given issuer 
    313313        @type key: basestring 
    314314        @param key: key by which these credentials should be referred to 
     
    317317        by calling isValidCredential method. 
    318318        """         
    319         for credential in credentials: 
    320             if not isinstance(credential, Assertion): 
     319        for assertion in assertions: 
     320            if not isinstance(assertion, Assertion): 
    321321                raise TypeError("Input credentials must be %r type; got %r" % 
    322                                 (Assertion, credential)) 
     322                                (Assertion, assertion)) 
    323323                 
    324             elif verifyCredentials and not self.isValidCredential(credential): 
     324            elif verifyCredentials and not self.isValidCredential(assertion): 
    325325                raise CredentialWalletError("Validity time error with " 
    326                                             "assertion %r" % credential) 
    327          
    328         # Check to see if there are existing credentials held under the same key 
    329         # If so, compare the expiry time.  The one with the latest expiry will  
    330         # be retained and the other ignored 
    331         bUpdateCred = True 
    332         if key in self.__assertionsMap: 
    333             # There is an existing certificate held with the same issuing 
    334             # host name as the new certificate 
    335             credentialOld = self.__assertionsMap[key].credential 
    336  
    337             # If the new certificate has an earlier expiry time then ignore it 
    338             bUpdateCred = (credential.conditions.notOnOrAfter >  
    339                            credentialOld.conditions.notOnOrAfter) 
    340              
    341         if bUpdateCred: 
    342             self.__assertionsMap[key] = credentials 
     326                                            "assertion %r" % assertion) 
     327         
     328        # Any existing credentials are overwritten 
     329        self.__assertionsMap[key] = assertions 
    343330 
    344331    def retrieveCredentials(self, key): 
     
    360347        for k, v in self.__assertionsMap.items(): 
    361348            creds = [credential for credential in v 
    362                      if not self.isValidCredential(credential)] 
     349                     if self.isValidCredential(credential)] 
    363350            if len(creds) > 0: 
    364                 self.__assertionsMap[k] = TypedList(Assertion) 
    365                 self.__assertionsMap[k].extend(creds) 
     351                self.__assertionsMap[k] = creds 
    366352            else: 
    367353                del self.__assertionsMap[k] 
     
    409395             
    410396        return _dict 
    411  
    412  
    413 class SAMLAttributeWallet(SAMLAssertionWallet): 
    414     """Wallet with functionality for retrieving assertions containing attribute  
    415     statements based on endpoint URI and issuer name 
    416     """ 
    417     __slots__ = ("__assertionsMapKeyedByURI",) 
    418      
    419     def __init__(self): 
    420         super(SAMLAttributeWallet, self).__init__() 
    421         self.__assertionsMapKeyedByURI = {} 
    422  
    423     def retrieveCredentialsByURI(self, issuerEndpoint): 
    424         """Get Property method for credentials keyed by issuing service URI 
    425         Credentials dict is read-only but also see addCredentials method 
    426          
    427         @rtype: dict 
    428         @return: cached ACs indexed by issuing service URI""" 
    429         return self.__assertionsMapKeyedByURI.get(issuerEndpoint) 
    430                 
    431     def audit(self): 
    432         """Check the credentials held in the wallet removing any that have 
    433         expired or are otherwise invalid.""" 
    434  
    435         log.debug("SAMLAssertionWallet.audit ...") 
    436          
    437         for issuerName, issuerEntry in self.__assertionsMap.items(): 
    438             if not self.isValidCredential(issuerEntry.credential): 
    439                 foundMatch = False 
    440                 endpoint = None 
    441                 for endpoint, v in self.__assertionsMapKeyedByURI.items(): 
    442                     if v.issuerName.value == issuerName: 
    443                         foundMatch = True 
    444                         break 
    445                  
    446                 if foundMatch: 
    447                     self.__assertionsMapKeyedByURI.pop(endpoint, None) 
    448                      
    449                 del self.__assertionsMap[issuerName] 
    450      
    451     def __getstate__(self): 
    452         '''Enable pickling for use with beaker.session''' 
    453         _dict = super(SAMLAttributeWallet, self).__getstate__() 
    454          
    455         for attrName in SAMLAttributeWallet.__slots__: 
    456             # Ugly hack to allow for derived classes setting private member 
    457             # variables 
    458             if attrName.startswith('__'): 
    459                 attrName = "_SAMLAttributeWallet" + attrName 
    460                  
    461             _dict[attrName] = getattr(self, attrName) 
    462              
    463         return _dict                    
    464      
    465      
    466 class SAMLAuthzDecisionWallet(SAMLAssertionWallet): 
    467     """Wallet with functionality for retrieving assertions containing  
    468     authorisation decision statements.  Credentials are keyed by resource Id""" 
    469     __slots__ = () 
    470      
    471     def addCredentials(self, assertions, verifyCredential=True): 
    472         """Add new assertions from a given issuer 
    473  
    474         @type assertions: SAML assertion 
    475         @param assertions: new assertion to be added 
    476         @type verifyCredential: bool 
    477         @param verifyCredential: if set to True, test validity of credential 
    478         by calling isValidCredential method. 
    479          
    480         @rtype: bool 
    481         @return: True if credential was added otherwise False.  - If an 
    482         existing certificate from the same issuer has a later expiry it will 
    483         take precedence and the new input certificate is ignored.""" 
    484          
    485         # Check input 
    486         if not isinstance(assertion, Assertion): 
    487             raise CredentialWalletError("Input assertion must be an " 
    488                                         "%r type object" % Assertion)         
    489  
    490         if verifyCredential and not self.isValidCredential(assertion): 
    491             raise CredentialWalletError("Validity time error with assertion %r" 
    492                                         % assertion) 
    493          
    494         # Check to see if there is an existing decision statement held for the 
    495         # same resource ID.  If so, compare the expiry time.  The one with the  
    496         # latest expiry will be retained and the other ignored 
    497         bUpdateCred = True 
    498          
    499         # Get the resource ID from the authorisation decision statement 
    500         # Nb. Assumes a SINGLE statement 
    501         if len(assertion.authzDecisionStatements) != 1: 
    502             raise CredentialWalletError("Expecting a single authorisation " 
    503                                         "decision statement passed with the " 
    504                                         "input assertion; found %r", 
    505                                         len(assertion.authzDecisionStatements)) 
    506          
    507         resourceId = assertion.authzDecisionStatements[0].resource         
    508         if resourceId in self.__assertionsMap: 
    509             # There is an existing certificate held with the same issuing 
    510             # host name as the new certificate 
    511             assertionOld = self.__assertionsMap[resourceId].credential 
    512  
    513             # If the new certificate has an earlier expiry time then ignore it 
    514             bUpdateCred = (assertion.conditions.notOnOrAfter >  
    515                            assertionOld.conditions.notOnOrAfter) 
    516  
    517         if bUpdateCred: 
    518             thisCredential = CredentialContainer(Assertion) 
    519             thisCredential.credential = assertion 
    520              
    521             if assertion.issuer.value: 
    522                 thisCredential.issuerName = assertion.issuer.value 
    523                  
    524             self.__assertionsMap[resourceId] = thisCredential 
    525                  
    526     def __getstate__(self): 
    527         '''Enable pickling for use with beaker.session''' 
    528         _dict = super(SAMLAuthzDecisionWallet, self).__getstate__() 
    529          
    530         for attrName in SAMLAuthzDecisionWallet.__slots__: 
    531             # Ugly hack to allow for derived classes setting private member 
    532             # variables 
    533             if attrName.startswith('__'): 
    534                 attrName = "_SAMLAuthzDecisionWallet" + attrName 
    535                  
    536             _dict[attrName] = getattr(self, attrName) 
    537              
    538         return _dict         
    539397         
    540398         
Note: See TracChangeset for help on using the changeset viewer.