Changeset 6039


Ignore:
Timestamp:
23/11/09 13:48:59 (10 years ago)
Author:
pjkersha
Message:

Unit tested SamlCredentialWallet?.

Location:
TI12-security/trunk/python
Files:
8 edited

Legend:

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

    r6034 r6039  
    148148    accessGranted = property(fget=_getAccessGranted) 
    149149 
     150class CredentialContainer(object): 
     151    """Container for cached credentials""" 
     152    ID_ATTRNAME = 'id' 
     153    ITEM_ATTRNAME = 'credential' 
     154    ISSUERNAME_ATTRNAME = 'issuerName' 
     155    ATTRIBUTE_AUTHORITY_URI_ATTRNAME = 'attributeAuthorityURI' 
     156    CREDENTIAL_TYPE_ATTRNAME = 'type' 
     157     
     158    __slots__ = ( 
     159        ID_ATTRNAME, 
     160        ITEM_ATTRNAME, 
     161        ISSUERNAME_ATTRNAME, 
     162        ATTRIBUTE_AUTHORITY_URI_ATTRNAME, 
     163        CREDENTIAL_TYPE_ATTRNAME 
     164    ) 
     165    __slots__ += tuple(["_CredentialContainer__%s" % n for n in __slots__]) 
     166     
     167    def __init__(self, type=None): 
     168        self.__type = None 
     169        self.type = type 
     170         
     171        self.__id = -1 
     172        self.__credential = None 
     173        self.__issuerName = None 
     174        self.__attributeAuthorityURI = None 
     175 
     176    def _getType(self): 
     177        return self.__type 
     178 
     179    def _setType(self, value): 
     180        if not isinstance(value, type): 
     181            raise TypeError('Expecting %r for "type" attribute; got %r' % 
     182                            (type, type(value)))        
     183        self.__type = value 
     184 
     185    type = property(_getType, _setType,  
     186                    doc="Type for credential - set to None for any type") 
     187 
     188    def _getId(self): 
     189        return self.__id 
     190 
     191    def _setId(self, value): 
     192        if not isinstance(value, int): 
     193            raise TypeError('Expecting int type for "id" attribute; got %r' % 
     194                            type(value)) 
     195        self.__id = value 
     196 
     197    id = property(_getId,  
     198                  _setId,  
     199                  doc="Numbered identifier for credential - " 
     200                      "set to -1 for new credentials") 
     201 
     202    def _getCredential(self): 
     203        return self.__credential 
     204 
     205    def _setCredential(self, value): 
     206        if self.type is not None and not isinstance(value, self.type): 
     207            raise TypeError('Expecting %r type for "credential" attribute; ' 
     208                            'got %r' % type(value)) 
     209        self.__credential = value 
     210 
     211    credential = property(_getCredential,  
     212                          _setCredential,  
     213                          doc="Credential object") 
     214 
     215    def _getIssuerName(self): 
     216        return self.__issuerName 
     217 
     218    def _setIssuerName(self, value): 
     219        self.__issuerName = value 
     220 
     221    issuerName = property(_getIssuerName,  
     222                          _setIssuerName,  
     223                          doc="Name of issuer of the credential") 
     224 
     225    def _getAttributeAuthorityURI(self): 
     226        return self.__attributeAuthorityURI 
     227 
     228    def _setAttributeAuthorityURI(self, value): 
     229        """String or None type are allowed - The URI may be set to None if 
     230        a local Attribute Authority instance is being invoked rather 
     231        one hosted via a remote URI 
     232        """ 
     233        if not isinstance(value, (basestring, type(None))): 
     234            raise TypeError('Expecting string or None type for ' 
     235                            '"attributeAuthorityURI"; got %r instead' %  
     236                            type(value)) 
     237        self.__attributeAuthorityURI = value 
     238 
     239    attributeAuthorityURI = property(_getAttributeAuthorityURI, 
     240                                     _setAttributeAuthorityURI,  
     241                                     doc="Attribute Authority Service URI") 
     242 
     243    def __getstate__(self): 
     244        '''Enable pickling''' 
     245        return dict([(attrName, getattr(self, attrName)) 
     246                     for attrName in self.__class__.__slots__]) 
     247         
     248    def __setstate__(self, attrDict): 
     249        '''Enable pickling for use with beaker.session''' 
     250        for attr, val in attrDict.items(): 
     251            setattr(self, attr, val) 
     252 
     253        
    150254 
    151255class CredentialWalletBase(object): 
     
    154258    __slots__ = ( 
    155259        "userId", 
    156         "attributeAuthorityURI" 
     260        "attributeAuthorityURI", 
    157261        "credentials", 
    158262        "credentialsKeyedByURI", 
     
    261365 
    262366    def _setAttributeAuthorityURI(self, value): 
    263         if not isinstance(value, basestring): 
    264             raise TypeError('Expecting string type for "attributeAuthorityURI";' 
    265                             ' got %r instead' % type(value)) 
     367        """String or None type are allowed - The URI may be set to None to  
     368        flag that a local Attribute Authority instance is being invoked rather 
     369        one hosted via a remote URI 
     370        """ 
     371        if not isinstance(value, (basestring, type(None))): 
     372            raise TypeError('Expecting string or None type for ' 
     373                            '"attributeAuthorityURI"; got %r instead' %  
     374                            type(value)) 
    266375        self.__attributeAuthorityURI = value 
    267376 
     
    400509        caCertFilePathList=[], 
    401510        sslCACertFilePathList=[], 
    402         attributeAuthorityURI=None, 
    403511        attributeAuthority=None, 
    404512        credentialRepository=None, 
     
    793901        super(CredentialWallet, self)._setAttributeAuthorityURI( 
    794902                                                        attributeAuthorityURI) 
    795                
    796         # Re-initialize local instance 
    797         self._attributeAuthority = CredentialWallet.propertyDefaults[ 
     903          
     904        if attributeAuthorityURI is not None:      
     905            # Re-initialize local instance 
     906            self._attributeAuthority = CredentialWallet.propertyDefaults[ 
    798907                                                        'attributeAuthority'] 
    799908             
     
    819928         
    820929        @type attributeAuthority: ndg.security.server.attributeauthority.AttributeAuthority 
    821         @param attributeAuthority: Attribute Authority instance.""" 
    822         if attributeAuthority is not None and \ 
    823            not isinstance(attributeAuthority, AttributeAuthority): 
    824             raise AttributeError("Expecting %r for attributeAuthority " 
    825                                  "attribute" % AttributeAuthority) 
     930        @param attributeAuthority: Attribute Authority instance. 
     931        """ 
     932        if not isinstance(attributeAuthority, (AttributeAuthority, type(None))): 
     933            raise AttributeError("Expecting %r or None type for " 
     934                                 "\"attributeAuthority\" attribute; got %r" %  
     935                                 (AttributeAuthority, type(attributeAuthority))) 
    826936             
    827937        self._attributeAuthority = attributeAuthority 
    828938         
    829939        # Re-initialize setting for remote service 
    830         self._attributeAuthorityURI = \ 
    831                     CredentialWallet.propertyDefaults['attributeAuthorityURI'] 
     940        self.attributeAuthorityURI = None 
    832941             
    833942    attributeAuthority = property(fget=_getAttributeAuthority, 
     
    9271036 
    9281037        # Check input 
    929         if not isinstance(credential, attCert): 
     1038        if not isinstance(attCert, AttCert): 
    9301039            raise CredentialWalletError("Credential must be an %r type object" % 
    9311040                                        AttCert) 
     
    9481057            # There is an existing certificate held with the same issuing 
    9491058            # host name as the new certificate 
    950             attCertOld = self.credentials[issuerName]['attCert'] 
     1059            attCertOld = self.credentials[issuerName].credential 
    9511060 
    9521061            # Get expiry times in datetime format to allow comparison 
     
    9601069                 
    9611070        if bUpdateCred: 
    962             # Update: Nb. -1 ID value flags item as new.  Items read in 
    963             # from the CredentialRepository during creation of the wallet will 
    964             # have +ve IDs previously allocated by the database 
    965             self.credentials[issuerName] = { 
    966                 'id': -1,  
    967                 'attCert': attCert, 
    968                 'issuerName': issuerName, 
    969                 'attributeAuthorityURI': attributeAuthorityURI 
    970             } 
    971  
     1071 
     1072            thisCredential = CredentialContainer(AttCert) 
     1073            thisCredential.credential = attCert 
     1074            thisCredential.issuerName = issuerName 
     1075            thisCredential.attributeAuthorityURI = attributeAuthorityURI 
     1076             
     1077            self.credentials[issuerName] = thisCredential  
     1078             
    9721079            if attributeAuthorityURI: 
    973                 self.credentialsKeyedByURI[attributeAuthorityURI] = \ 
    974                     self.credentials[issuerName] 
     1080                self.credentialsKeyedByURI[ 
     1081                    attributeAuthorityURI] = thisCredential 
    9751082             
    9761083            # Update the Credentials Repository - the permanent store of user 
     
    9981105        # P J Kershaw 12/09/05 
    9991106        for key, val in self.credentials.items(): 
    1000             if not val['attCert'].isValid(chkSig=False): 
     1107            if not val.credential.isValid(chkSig=False): 
    10011108                del self.credentials[key] 
    10021109 
     
    10201127 
    10211128        # Update the database - only add new entries i.e. with an ID of -1 
    1022         attCertList = [i['attCert'] for i in self.credentials.values()  
    1023                        if i['id'] == -1] 
     1129        attCertList = [i.credential for i in self.credentials.values()  
     1130                       if i.id == -1] 
    10241131 
    10251132        self.credentialRepository.addCredentials(self.userId, attCertList) 
     
    15651672                    # original provenance and contain at least one of the 
    15661673                    # required roles 
    1567                     attCert = self.credentials[hostName]['attCert'] 
     1674                    attCert = self.credentials[hostName].credential 
    15681675                     
    15691676                    if hostName in trustedHostInfo and attCert.isOriginal():                         
     
    17171824    ESG_NAME_ID_FORMAT = EsgSamlNamespaces.NAMEID_FORMAT 
    17181825     
    1719     ATTRIBUTE_AUTHORITY_URI_OPTNAME = 'attributeAuthorityURI' 
    17201826    ISSUER_DN_OPTNAME = 'issuerDN' 
    17211827    CLOCK_SKEW_OPTNAME = 'clockSkew' 
    17221828     
    17231829    CONFIG_FILE_OPTNAMES = ( 
    1724         ATTRIBUTE_AUTHORITY_URI_OPTNAME, 
    17251830        ISSUER_DN_OPTNAME,                  
    17261831        CLOCK_SKEW_OPTNAME             
     
    19632068        log.debug("Adding credentials into wallet...") 
    19642069        for assertion in response.assertions: 
    1965             self.addCredential(assertion) 
     2070            self.addCredential(assertion,  
     2071                               attributeAuthorityURI=self.attributeAuthorityURI) 
    19662072 
    19672073    def addCredential(self,  
     
    19972103        # ingored 
    19982104        bUpdateCred = True 
    1999         issuerName = attCert['issuerName'] 
     2105        issuerName = credential.issuer.value 
    20002106         
    20012107        if issuerName in self.credentials: 
    20022108            # There is an existing certificate held with the same issuing 
    20032109            # host name as the new certificate 
    2004             attCertOld = self.credentials[issuerName]['attCert'] 
    2005  
    2006             # Get expiry times in datetime format to allow comparison 
    2007             dtAttCertOldNotAfter = attCertOld.getValidityNotAfter(\ 
    2008                                                             asDatetime=True) 
    2009             dtAttCertNotAfter = attCert.getValidityNotAfter(asDatetime=True) 
     2110            credentialOld = self.credentials[issuerName]['assertion'] 
    20102111 
    20112112            # If the new certificate has an earlier expiry time then ignore it 
    2012             bUpdateCred = dtAttCertNotAfter > dtAttCertOldNotAfter 
    2013  
    2014                  
     2113            bUpdateCred = (credential.conditions.notOnOrAfter >  
     2114                           credentialOld.conditions.notOnOrAfter) 
     2115 
    20152116        if bUpdateCred: 
    2016             # Update: Nb. -1 ID value flags item as new.  Items read in 
    2017             # from the CredentialRepository during creation of the wallet will 
    2018             # have +ve IDs previously allocated by the database 
    2019             self.credentials[issuerName] = { 
    2020                 'id': -1,  
    2021                 'attCert': attCert, 
    2022                 'issuerName': issuerName, 
    2023                 'attributeAuthorityURI': attributeAuthorityURI 
    2024             } 
    2025  
     2117            thisCredential = CredentialContainer(Assertion) 
     2118            thisCredential.credential = credential 
     2119            thisCredential.issuerName = issuerName 
     2120            thisCredential.attributeAuthorityURI = attributeAuthorityURI 
     2121             
     2122            self.credentials[issuerName] = thisCredential 
     2123             
    20262124            if attributeAuthorityURI: 
    2027                 self.credentialsKeyedByURI[attributeAuthorityURI] = \ 
    2028                     self.credentials[issuerName] 
    2029              
     2125                self.credentialsKeyedByURI[ 
     2126                    attributeAuthorityURI] = thisCredential  
     2127 
    20302128            # Update the Credentials Repository - the permanent store of user 
    20312129            # authorisation credentials.  This allows credentials for previous 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/attributeauthority.py

    r6034 r6039  
    3030from saml.utils import SAMLDateTime 
    3131from saml.saml2.core import (Response, Assertion, Attribute, AttributeStatement, 
    32                              SAMLVersion, Subject, NameID, Issuer,  
    33                              AttributeQuery, XSStringAttributeValue, Conditions, 
    34                              Status, StatusCode, StatusMessage) 
     32                             SAMLVersion, Subject, NameID, Issuer, Conditions, 
     33                             AttributeQuery, XSStringAttributeValue, Status,  
     34                             StatusCode, StatusMessage) 
    3535 
    3636from ndg.security.common.saml_utils.esg import EsgSamlNamespaces 
     
    19081908    SQLQUERY_USERID_KEYNAME = 'userId' 
    19091909     
     1910    ISSUER_NAME_FORMAT = Issuer.X509_SUBJECT 
     1911    ISSUER_NAME_OPTNAME = 'issuerName' 
    19101912    CONNECTION_STRING_OPTNAME = 'connectionString' 
    19111913    ATTRIBUTE_SQLQUERY_OPTNAME = 'attributeSqlQuery' 
     
    19421944            raise AttributeInterfaceConfigError("SQLAlchemy is not installed") 
    19431945         
     1946        self.__issuerName = None 
    19441947        self.__connectionString = None 
    19451948        self.__attributeSqlQuery = None 
     
    19972000            else: 
    19982001                setattr(self, name, val) 
     2002 
     2003    def _getIssuerName(self): 
     2004        return self.__issuerName 
     2005 
     2006    def _setIssuerName(self, value): 
     2007        if not isinstance(value, basestring): 
     2008            raise TypeError('Expecting string type for "%s" attribute; got %r'% 
     2009                            (SQLAlchemyAttributeInterface.ISSUER_NAME_OPTNAME, 
     2010                             type(value))) 
     2011 
     2012        self.__issuerName = value 
     2013 
     2014    issuerName = property(_getIssuerName,  
     2015                          _setIssuerName,  
     2016                          doc="The name of the issuing organisation.  This is " 
     2017                              "expected to be an X.509 Distinguished Name") 
    19992018             
    20002019    def _getSamlAssertionLifetime(self): 
     
    22152234        assertion.id = str(uuid4()) 
    22162235        assertion.issueInstant = response.issueInstant 
     2236     
     2237        assertion.issuer = Issuer() 
     2238        assertion.issuer.value = self.issuerName 
     2239        assertion.issuer.format = Issuer.X509_SUBJECT 
    22172240 
    22182241        assertion.conditions = Conditions() 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/authz.py

    r6033 r6039  
    428428         
    429429        # Check for existing credentials cached in wallet             
    430         credential = credentialWallet.credentialsKeyedByURI.get( 
     430        credentialItem = credentialWallet.credentialsKeyedByURI.get( 
    431431                                                    attributeAuthorityURI, {}) 
    432432         
    433         attrCert = credential.get('attCert') 
     433        attrCert = credentialItem.credential 
    434434        if attrCert is not None: 
    435435            log.debug("PIPMiddleware._getAttributeCertificate: retrieved " 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/config/attributeauthority/sitea/siteAUserRoles.py

    r6018 r6039  
    2121                                                    UserIdNotKnown) 
    2222from saml.common.xml import SAMLConstants 
    23 from saml.saml2.core import (Assertion, Attribute, AttributeStatement,  
    24                              SAMLVersion, Subject, NameID,  
    25                              XSStringAttributeValue, Conditions) 
     23from saml.saml2.core import (Assertion, Attribute, AttributeStatement, Issuer, 
     24                             SAMLVersion, Subject, NameID, Conditions, 
     25                             XSStringAttributeValue) 
    2626 
    2727 
     
    8383    VALID_REQUESTOR_IDS = ("/O=Site A/CN=Authorisation Service",  
    8484                           "/O=Site B/CN=Authorisation Service") 
     85     
     86    ISSUER_NAME = "/O=Site A/CN=Attribute Authority" 
     87     
    8588    INSUFFICIENT_PRIVILEGES_REQUESTOR_ID = "/O=Site B/CN=Authorisation Service" 
    8689     
     
    125128        assertion.id = str(uuid4()) 
    126129        assertion.issueInstant = response.issueInstant 
     130     
     131        assertion.issuer = Issuer() 
     132        assertion.issuer.value = TestUserRoles.ISSUER_NAME 
     133        assertion.issuer.format = Issuer.X509_SUBJECT 
    127134         
    128135        assertion.conditions = Conditions() 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/__init__.py

    r6033 r6039  
    6363        'http://localhost:%s/AttributeAuthority/saml' % \ 
    6464                                    SITEB_ATTRIBUTEAUTHORITY_PORTNUM 
     65                                     
     66    SITEA_SAML_ISSUER_NAME = "/O=Site A/CN=Attribute Authority" 
    6567     
    6668    SESSIONMANAGER_PORTNUM = 5500 
     
    110112    ) 
    111113    N_ATTRIBUTE_VALUES = len(ATTRIBUTE_VALUES) 
     114     
     115    VALID_REQUESTOR_IDS = ("/O=Site A/CN=Authorisation Service",  
     116                           "/O=Site B/CN=Authorisation Service") 
    112117     
    113118    def __init__(self, *arg, **kw): 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/attributeauthority/test_sqlalchemyattributeinterface.cfg

    r6018 r6039  
    11[DEFAULT] 
    22openIdStem = https://openid.localhost/ 
     3attributeInterface.issuerName = /O=Site A/CN=Attribute Authority 
    34attributeInterface.samlSubjectSqlQuery = select count(*) from users where '%(openIdStem)s' || openid_identifier = '${userId}' 
    45attributeInterface.samlAttribute2SqlQuery.1 = "urn:esg:first:name" "select firstname from users where '%(openIdStem)s' || openid_identifier = '${userId}'" 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/credentialwallet/test_credentialwallet.py

    r6033 r6039  
    1515import traceback 
    1616 
     17from saml.xml.etree import AssertionElementTree 
     18 
    1719from ndg.security.test.unit import BaseTestCase 
    1820 
    1921from ndg.security.common.utils.configfileparsers import ( 
    2022                                                    CaseSensitiveConfigParser) 
     23from ndg.security.common.utils.etree import prettyPrint 
    2124from ndg.security.common.X509 import X509CertParse 
    2225from ndg.security.common.credentialwallet import (CredentialWallet,  
     
    187190class SamlCredentialWalletTestCase(BaseTestCase): 
    188191    def __init__(self, *arg, **kw): 
    189         super(CredentialWalletTestCase, self).__init__(*arg, **kw) 
     192        super(SamlCredentialWalletTestCase, self).__init__(*arg, **kw) 
    190193        self.startSiteAAttributeAuthority() 
    191194         
    192195    def test01(self): 
    193196        wallet = SamlCredentialWallet() 
     197         
     198        wallet.userId = SamlCredentialWalletTestCase.OPENID_URI 
     199        wallet.issuerDN = SamlCredentialWalletTestCase.VALID_REQUESTOR_IDS[0]         
    194200        wallet.attributeAuthorityURI = \ 
    195201            SamlCredentialWalletTestCase.SITEA_ATTRIBUTEAUTHORITY_SAML_URI 
     202         
    196203        wallet.attributeQuery() 
     204        self.assert_(len(wallet.credentials) == 1) 
     205        self.assert_( 
     206            SamlCredentialWalletTestCase.SITEA_ATTRIBUTEAUTHORITY_SAML_URI in \ 
     207            wallet.credentialsKeyedByURI) 
     208        self.assert_(SamlCredentialWalletTestCase.SITEA_SAML_ISSUER_NAME in \ 
     209                     wallet.credentials) 
     210        self.assert_( 
     211            wallet.credentials[ 
     212                SamlCredentialWalletTestCase.SITEA_SAML_ISSUER_NAME 
     213            ].credential.subject.nameID.value == \ 
     214            wallet.userId) 
     215         
     216        assertion = wallet.credentials[ 
     217            SamlCredentialWalletTestCase.SITEA_SAML_ISSUER_NAME 
     218        ].credential 
     219        samlAssertionElem = AssertionElementTree.toXML(assertion) 
     220        print("SAML Assertion:\n%s" % prettyPrint(samlAssertionElem)) 
    197221                                                                 
    198222if __name__ == "__main__": 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/saml/test_samlinterface.py

    r6034 r6039  
    6060        samlResponse.issuer = Issuer() 
    6161         
    62         # SAML 2.0 spec says fromat must be omitted 
     62        # SAML 2.0 spec says format must be omitted 
    6363        #samlResponse.issuer.format = Issuer.X509_SUBJECT 
    6464        samlResponse.issuer.value = \ 
Note: See TracChangeset for help on using the changeset viewer.