Changeset 5738


Ignore:
Timestamp:
18/09/09 15:10:22 (11 years ago)
Author:
pjkersha
Message:

saml.xml.etree: important fixes to ElementTree based Status element serialisation and de-serialisation
ndg.security.server.attributeauthority: added clockSkew parameter to provide some leeway in SAML attribute query clock checks. Also added StatusMessage? element for additional error info in responses.
ndg.security.common.soap.client: added check of HTTP Content-type in SOAP responses.

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

Legend:

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

    r5681 r5738  
    1515class SOAPClientError(Exception): 
    1616    """Base class for SOAP Client exceptions""" 
    17      
    18 class HTTPException(SOAPClientError): 
    19     """Server returned HTTP code error code""" 
    20     def __init__(self, *arg, **kw): 
    21         Exception.__init__(self, *arg, **kw) 
    22         self.urllib2Response = None 
    2317 
    2418class SOAPParseError(SOAPClientError): 
     
    2721            
    2822class SOAPClientBase(object): 
    29     """Handle client request to a SOAP Service""" 
     23    """Handle client request to a SOAP Service 
     24    @cvar RESPONSE_CONTENT_TYPES: expected content type to be returned in a response 
     25    from a service 
     26    @type RESPONSE_CONTENT_TYPES: string 
     27    """ 
     28    RESPONSE_CONTENT_TYPES = ('text/xml', ) 
     29     
    3030    def __init__(self): 
    3131        self.__responseEnvelopeClass = None 
     
    9191    """Interface for SOAP responses""" 
    9292 
    93  
     93import httplib 
    9494import urllib2 
     95from urllib import addinfourl 
     96   
     97class UrlLib2SOAPClientError(SOAPClientError): 
     98    """Specialisation to enable the urllib2 response to be included in the 
     99    exception instance as context information for the caller 
     100    """ 
     101    URLLIB2RESPONSE_TYPE = addinfourl 
     102     
     103    def __init__(self, *arg, **kw): 
     104        Exception.__init__(self, *arg, **kw) 
     105        self.__urllib2Response = None 
     106 
     107    def _getUrllib2Response(self): 
     108        return self.__urllib2Response 
     109 
     110    def _setUrllib2Response(self, value): 
     111        if not isinstance(value, UrlLib2SOAPClientError.URLLIB2RESPONSE_TYPE): 
     112            raise TypeError('Expecting %r type for "urllib2Response"; got %r' % 
     113                            (UrlLib2SOAPClientError.URLLIB2RESPONSE_TYPE,  
     114                             type(value))) 
     115        self.__urllib2Response = value 
     116 
     117    urllib2Response = property(_getUrllib2Response,  
     118                               _setUrllib2Response,  
     119                               doc="Urllib2Response") 
     120 
     121 
     122class SOAPResponseError(UrlLib2SOAPClientError): 
     123    """Raise for invalid SOAP response from server""" 
     124        
     125class HTTPException(UrlLib2SOAPClientError): 
     126    """Server returned HTTP code error code""" 
    95127 
    96128class UrlLib2SOAPRequest(SOAPRequestBase):   
     
    141173        if not isinstance(value, urllib2.OpenerDirector): 
    142174            raise TypeError("Setting opener: expecting %r; got %r" %  
    143                             (urllib2.OpenerDirector, value.__class__)) 
     175                            (urllib2.OpenerDirector, type(value))) 
    144176        self.__openerDirector = value 
    145177 
     
    153185         
    154186        if not isinstance(soapRequest, UrlLib2SOAPRequest): 
    155             raise TypeError('UrlLib2SOAPClient.makeRequest: expecting %r ' 
     187            raise TypeError('UrlLib2SOAPClient.send: expecting %r ' 
    156188                            'derived type for SOAP request, got %r' %  
    157                             (self.responseEnvelopeClass,soapRequest.__class__)) 
     189                            (self.responseEnvelopeClass, type(soapRequest))) 
    158190             
    159191        if not isinstance(soapRequest.envelope, self.responseEnvelopeClass): 
    160             raise TypeError('UrlLib2SOAPClient.makeRequest: expecting %r ' 
     192            raise TypeError('UrlLib2SOAPClient.send: expecting %r ' 
    161193                            'derived type for SOAP envelope, got %r' %  
    162                             (self.responseEnvelopeClass,soapRequest.__class__)) 
     194                            (self.responseEnvelopeClass, type(soapRequest))) 
    163195                             
    164196        if self.timeout is not None: 
     
    172204                                            soapRequestStr,  
    173205                                            *arg) 
    174         if response.code != 200: 
     206        if response.code != httplib.OK: 
    175207            output = response.read() 
    176208            excep = HTTPException("Response is: %d %s" % (response.code,  
     
    179211            raise excep 
    180212         
    181          
     213        if response.headers.typeheader not in \ 
     214           UrlLib2SOAPClient.RESPONSE_CONTENT_TYPES: 
     215            responseType = ', '.join(UrlLib2SOAPClient.RESPONSE_CONTENT_TYPES) 
     216            excep = SOAPResponseError("Expecting %r response type; got %r for " 
     217                                      "request to [%s]" %  
     218                                      (responseType,  
     219                                       response.headers.typeheader, 
     220                                       soapRequest.url)) 
     221            excep.urllib2Response = response 
     222            raise excep 
     223             
    182224        soapResponse.fileObject = response 
    183225        soapResponse.envelope = self.responseEnvelopeClass()   
     
    186228            soapResponse.envelope.parse(soapResponse.fileObject) 
    187229        except Exception, e: 
    188             raise SOAPParseError("Error parsing response for request to [%s]: " 
    189                                  "%s" 
    190                                  % (soapRequest.url, e)) 
     230            raise SOAPParseError("%r type error raised parsing response for " 
     231                                 "request to [%s]: %s" 
     232                                 % (type(e), soapRequest.url, e)) 
    191233             
    192234        return soapResponse 
    193  
    194          
    195      
    196      
  • TI12-security/trunk/python/ndg_security_saml/saml/saml2/core.py

    r5663 r5738  
    12511251    '''Implementation of SAML 2.0 Status Message''' 
    12521252 
     1253    DEFAULT_ELEMENT_LOCAL_NAME = "StatusMessage" 
     1254    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20P_NS,  
     1255                                 DEFAULT_ELEMENT_LOCAL_NAME, 
     1256                                 SAMLConstants.SAML20P_PREFIX) 
     1257     
    12531258    def __init__(self): 
    12541259        # Value attribute URI. 
    12551260        self.__value = None         
    1256         self.__qname = None 
     1261        self.__qname = QName(StatusMessage.DEFAULT_ELEMENT_NAME.namespaceURI, 
     1262                             StatusMessage.DEFAULT_ELEMENT_NAME.localPart, 
     1263                             StatusMessage.DEFAULT_ELEMENT_NAME.prefix) 
    12571264               
    12581265    def _getValue(self): 
     
    12621269        if not isinstance(value, basestring): 
    12631270            raise TypeError("\"value\" must be a basestring derived type, " 
    1264                             "got %r" % value.__class__) 
     1271                            "got %r" % type(value)) 
    12651272             
    12661273        self.__value = value 
     
    15171524        @param newStatusMessage the Message of this Status 
    15181525        ''' 
    1519         if not isinstance(value, basestring): 
     1526        if not isinstance(value, StatusMessage): 
    15201527            raise TypeError('"statusMessage" must be a %r derived type, ' 
    1521                             "got %r" % (basestring, type(value))) 
     1528                            "got %r" % (StatusMessage, type(value))) 
    15221529             
    15231530        self.__statusMessage = value 
  • TI12-security/trunk/python/ndg_security_saml/saml/test/test_saml.py

    r5621 r5738  
    2323from saml.saml2.core import SAMLVersion, Attribute, AttributeStatement, \ 
    2424    Assertion, AttributeQuery, Response, Issuer, Subject, NameID, StatusCode, \ 
    25     Status, Conditions, XSStringAttributeValue, XSGroupRoleAttributeValue 
     25    StatusMessage, Status, Conditions, XSStringAttributeValue, \ 
     26    XSGroupRoleAttributeValue 
    2627from saml.common.xml import SAMLConstants 
    2728from saml.xml.etree import prettyPrint, AssertionElementTree, \ 
     
    358359        response.status = Status() 
    359360        response.status.statusCode = StatusCode() 
    360         response.status.statusCode.value = StatusCode.SUCCESS_URI         
    361                  
     361        response.status.statusCode.value = StatusCode.SUCCESS_URI 
     362        response.status.statusMessage = StatusMessage()         
     363        response.status.statusMessage.value = "Response created successfully" 
     364            
    362365        assertion = self._createAssertionHelper() 
    363366         
  • TI12-security/trunk/python/ndg_security_saml/saml/xml/etree.py

    r5663 r5738  
    4141    AuthnStatement, AuthzDecisionStatement, Assertion, Conditions, \ 
    4242    AttributeValue, AttributeQuery, Subject, NameID, Issuer, Response, \ 
    43     Status, StatusCode, Advice, XSStringAttributeValue, \ 
    44     XSGroupRoleAttributeValue 
     43    Status, StatusCode, StatusMessage, StatusDetail, Advice, \ 
     44    XSStringAttributeValue, XSGroupRoleAttributeValue 
    4545from saml.common import SAMLVersion 
    4646from saml.common.xml import SAMLConstants 
    4747from saml.common.xml import QName as GenericQName 
    48 from saml.xml import XMLTypeParseError 
     48from saml.xml import XMLTypeParseError, UnknownAttrProfile 
    4949from saml.utils import SAMLDateTime 
    5050 
     
    10751075        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME: 
    10761076            raise XMLTypeParseError("No \"%s\" element found" % 
    1077                                       cls.DEFAULT_ELEMENT_LOCAL_NAME) 
     1077                                    cls.DEFAULT_ELEMENT_LOCAL_NAME) 
    10781078             
    10791079        format = elem.attrib.get(cls.FORMAT_ATTRIB_NAME) 
    10801080        if format is None: 
    10811081            raise XMLTypeParseError('No "%s" attribute found in "%s" ' 
    1082                                       'element' % 
    1083                                       (format, 
    1084                                        cls.DEFAULT_ELEMENT_LOCAL_NAME)) 
     1082                                    'element' % 
     1083                                    (cls.FORMAT_ATTRIB_NAME, 
     1084                                     cls.DEFAULT_ELEMENT_LOCAL_NAME)) 
    10851085        nameID = NameID() 
    10861086        nameID.format = format 
     
    11451145         
    11461146class StatusCodeElementTree(StatusCode): 
    1147     """Represent a SAML Name Identifier in XML using ElementTree""" 
     1147    """Represent a SAML Status Code in XML using ElementTree""" 
    11481148     
    11491149    @classmethod 
     
    11601160                                                           type(statusCode))) 
    11611161             
     1162        attrib = { 
     1163            cls.VALUE_ATTRIB_NAME: statusCode.value 
     1164        } 
    11621165        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME)) 
    1163         elem = ElementTree.Element(tag) 
     1166        elem = ElementTree.Element(tag, **attrib) 
    11641167         
    11651168        ElementTree._namespace_map[statusCode.qname.namespaceURI 
    11661169                                   ] = statusCode.qname.prefix 
    1167          
    1168         elem.text = statusCode.value 
    11691170 
    11701171        return elem 
     
    11851186        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME: 
    11861187            raise XMLTypeParseError('No "%s" element found' % 
    1187                                       cls.DEFAULT_ELEMENT_LOCAL_NAME) 
     1188                                    cls.DEFAULT_ELEMENT_LOCAL_NAME) 
    11881189             
    11891190        statusCode = StatusCode() 
     1191             
     1192        value = elem.attrib.get(cls.VALUE_ATTRIB_NAME) 
     1193        if value is None: 
     1194            raise XMLTypeParseError('No "%s" attribute found in "%s" element' % 
     1195                                    (cls.VALUE_ATTRIB_NAME, 
     1196                                     cls.DEFAULT_ELEMENT_LOCAL_NAME)) 
     1197        statusCode.value = value 
     1198         
     1199        return statusCode 
     1200 
     1201         
     1202class StatusMessageElementTree(StatusMessage): 
     1203    """Represent a SAML Status Message in XML using ElementTree""" 
     1204     
     1205    @classmethod 
     1206    def toXML(cls, statusMessage): 
     1207        """Create an XML representation of the input SAML Name Status Message 
     1208         
     1209        @type statusMessage: saml.saml2.core.StatusMessage 
     1210        @param statusMessage: SAML Status Message 
     1211        @rtype: ElementTree.Element 
     1212        @return: Status Code as ElementTree XML element""" 
     1213         
     1214        if not isinstance(statusMessage, StatusMessage): 
     1215            raise TypeError("Expecting %r class got %r" % (StatusMessage,  
     1216                                                           type(statusMessage))) 
     1217             
     1218        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME)) 
     1219        elem = ElementTree.Element(tag) 
     1220         
     1221        ElementTree._namespace_map[statusMessage.qname.namespaceURI 
     1222                                   ] = statusMessage.qname.prefix 
     1223         
     1224        elem.text = statusMessage.value 
     1225 
     1226        return elem 
     1227 
     1228    @classmethod 
     1229    def fromXML(cls, elem): 
     1230        """Parse ElementTree element into a SAML StatusMessage object 
     1231         
     1232        @type elem: ElementTree.Element 
     1233        @param elem: Status Code as ElementTree XML element 
     1234        @rtype: saml.saml2.core.StatusMessage 
     1235        @return: SAML Status Message 
     1236        """ 
     1237        if not ElementTree.iselement(elem): 
     1238            raise TypeError("Expecting %r input type for parsing; got %r" % 
     1239                            (ElementTree.Element, elem)) 
     1240 
     1241        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME: 
     1242            raise XMLTypeParseError('No "%s" element found' % 
     1243                                    cls.DEFAULT_ELEMENT_LOCAL_NAME) 
     1244             
     1245        statusMessage = StatusMessage() 
    11901246        if elem.text is not None: 
    1191             statusCode.value = elem.text.strip()  
    1192          
    1193         return statusCode 
     1247            statusMessage.value = elem.text.strip()  
     1248         
     1249        return statusMessage 
    11941250 
    11951251 
     
    12181274        elem.append(statusCodeElem) 
    12191275         
     1276        # Status message is optional 
     1277        if status.statusMessage is not None and \ 
     1278           status.statusMessage.value is not None: 
     1279            statusMessageElem = StatusMessageElementTree.toXML( 
     1280                                                        status.statusMessage) 
     1281            elem.append(statusMessageElem) 
     1282         
     1283        if status.statusDetail is not None: 
     1284            raise NotImplementedError("StatusDetail XML serialisation is not " 
     1285                                      "implemented") 
     1286             
    12201287        return elem 
    12211288 
     
    12371304                                      Status.DEFAULT_ELEMENT_LOCAL_NAME) 
    12381305             
    1239         if len(elem) != 1: 
    1240             raise XMLTypeParseError("Expecting single StatusCode child " 
    1241                                       "element for SAML Status element") 
     1306        if len(elem) < 1: 
     1307            raise XMLTypeParseError("Expecting a StatusCode child element for " 
     1308                                    "SAML Status element") 
    12421309             
    12431310        status = Status() 
    1244         status.statusCode = StatusCodeElementTree.fromXML(elem[0]) 
    1245          
     1311        for childElem in elem: 
     1312            localName = QName.getLocalPart(childElem.tag) 
     1313            if localName == StatusCode.DEFAULT_ELEMENT_LOCAL_NAME: 
     1314                status.statusCode = StatusCodeElementTree.fromXML(childElem) 
     1315                 
     1316            elif localName == StatusMessage.DEFAULT_ELEMENT_LOCAL_NAME: 
     1317                status.statusMessage = StatusMessageElementTree.fromXML( 
     1318                                                                childElem) 
     1319            elif localName == StatusDetail.DEFAULT_ELEMENT_LOCAL_NAME: 
     1320                raise NotImplementedError("XML parse of %s element is not " 
     1321                                    "implemented" % 
     1322                                    StatusDetail.DEFAULT_ELEMENT_LOCAL_NAME) 
     1323            else: 
     1324                raise XMLTypeParseError("Status child element name %r not " 
     1325                                        "recognised" % localName) 
     1326        
    12461327        return status 
    12471328     
  • TI12-security/trunk/python/ndg_security_saml/setup.py

    r5590 r5738  
    2020setup( 
    2121    name =                      'ndg_security_saml', 
    22     version =                   '0.1.0', 
     22    version =                   '0.1.1', 
    2323    description =               'NERC DataGrid SAML Implementation', 
    2424    long_description =          ('SAML 2.0 implementation for use with NDG ' 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/attributeauthority.py

    r5729 r5738  
    3131    AttributeStatement, SAMLVersion, Subject, NameID, Issuer, AttributeQuery, \ 
    3232    XSStringAttributeValue, XSGroupRoleAttributeValue, Conditions, Status, \ 
    33     StatusCode 
     33    StatusCode, StatusMessage 
    3434     
    3535from saml.common.xml import SAMLConstants 
     
    131131    # in the config 
    132132    propertyDefaults = {  
    133         'name':                 '', 
    134         'signingCertFilePath':  '', 
    135         'signingPriKeyFilePath':'', 
    136         'signingPriKeyPwd':     None, 
    137         'caCertFilePathList':   [], 
    138         'attCertLifetime':      -1, 
    139         'attCertNotBeforeOff':  0., 
    140         'attCertFileName':      '', 
    141         'attCertFileLogCnt':    0, 
    142         'mapConfigFilePath':    '', 
    143         'attCertDir':           '', 
    144         'dnSeparator':          '/', 
    145         ATTRIBUTE_INTERFACE_KEYNAME: attributeInterfacePropertyDefaults 
     133        'name':                         '', 
     134        'signingCertFilePath':          '', 
     135        'signingPriKeyFilePath':        '', 
     136        'signingPriKeyPwd':             None, 
     137        'caCertFilePathList':           [], 
     138        'attCertLifetime':              -1, 
     139        'attCertNotBeforeOff':          0., 
     140        'clockSkew':                    0., 
     141        'attCertFileName':              '', 
     142        'attCertFileLogCnt':            0, 
     143        'mapConfigFilePath':            '', 
     144        'attCertDir':                   '', 
     145        'dnSeparator':                  '/', 
     146        ATTRIBUTE_INTERFACE_KEYNAME:    attributeInterfacePropertyDefaults 
    146147    } 
    147148     
     
    209210        return self.__attCertNotBeforeOff 
    210211 
     212    def _getClockSkew(self): 
     213        return self.__clockSkew 
     214 
    211215    def _getAttCertDir(self): 
    212216        return self.__attCertDir 
     
    214218    def _getAttributeInterface(self): 
    215219        return self.__attributeInterface 
    216  
    217     def _getMapConfigFile(self): 
    218         return self.__mapConfigFile 
    219  
    220     def _getName(self): 
    221         return self.__name 
    222220 
    223221    def _getTrustedHostInfo(self): 
     
    271269            raise TypeError('Expecting float, int, long or string type for ' 
    272270                            '"attCertNotBeforeOff"; got %r' % type(value)) 
     271 
     272    def _setClockSkew(self, value): 
     273        if isinstance(value, (float, int, long)): 
     274            self.__clockSkew = timedelta(seconds=value) 
     275             
     276        elif isinstance(value, basestring): 
     277            self.__clockSkew = timedelta(seconds=float(value)) 
     278        else: 
     279            raise TypeError('Expecting float, int, long or string type for ' 
     280                            '"clockSkew"; got %r' % type(value)) 
    273281 
    274282    def _setAttCertDir(self, value): 
     
    287295                                                (value, osError.strerror)) 
    288296        self.__attCertDir = value 
    289  
    290     def _setMapConfigFilePath(self, value): 
    291         self.__mapConfigFilePath = value 
    292297 
    293298    def _setTrustedHostInfo(self, value): 
     
    421426    mapConfigFilePath = property(fget=_getMapConfigFilePath, 
    422427                                 fset=_setMapConfigFilePath, 
    423                                  doc="File path for Role Mapping configuration")  
     428                                 doc="File path for Role Mapping " 
     429                                     "configuration")  
    424430 
    425431    def setPropFilePath(self, val=None): 
     
    473479        @type val: basestring 
    474480        @param val: section name""" 
    475         log.debug("Setting property file section name") 
    476481        if not val: 
    477482            val = os.environ.get('NDGSEC_AA_PROPFILESECTION', 'DEFAULT') 
     
    482487       
    483488        self.__propFileSection = val 
    484         log.debug("Properties file section set to: %s" % val) 
     489        log.debug("Properties file section set to: \"%s\"" % val) 
    485490         
    486491    def getPropFileSection(self): 
     
    524529        @rtype: basestring 
    525530        @return: section name''' 
    526         log.debug("Getting property file prefix") 
    527531        return self.__propPrefix 
    528532    
     
    564568                                   doc="Attribute certificate clock skew in " 
    565569                                       "seconds") 
     570 
     571    clockSkew = property(fget=_getClockSkew,  
     572                         fset=_setClockSkew,  
     573                         doc="Allow a clock skew in seconds for SAML Attribute" 
     574                             " Query issueInstant parameter check") 
    566575 
    567576    attCertDir = property(fget=_getAttCertDir,  
     
    10611070        samlResponse.status = Status() 
    10621071        samlResponse.status.statusCode = StatusCode() 
     1072        samlResponse.status.statusMessage = StatusMessage() 
    10631073        samlResponse.status.statusCode.value = StatusCode.SUCCESS_URI 
    10641074         
     
    10701080        # Attribute Query validation ... 
    10711081        utcNow = datetime.utcnow() 
    1072         if attributeQuery.issueInstant >= utcNow: 
     1082        if attributeQuery.issueInstant >= utcNow + self.clockSkew: 
    10731083            msg = ('SAML Attribute Query issueInstant [%s] is at or after ' 
    10741084                   'the current clock time [%s]') % \ 
     
    10771087                       
    10781088            samlResponse.status.statusCode.value = StatusCode.REQUESTER_URI 
    1079             samlResponse.status.statusMessage = msg 
     1089            samlResponse.status.statusMessage = StatusMessage() 
     1090            samlResponse.status.statusMessage.value = msg 
    10801091            return samlResponse 
    10811092             
     
    10951106                                "urn:esg:openid")) 
    10961107            samlResponse.status.statusCode.value = StatusCode.REQUESTER_URI 
    1097             samlResponse.status.statusMessage = \ 
     1108            samlResponse.status.statusMessage.value = \ 
    10981109                                "Subject Name ID format is not recognised" 
    10991110            return samlResponse 
     
    11041115                                "urn:esg:issuer")) 
    11051116            samlResponse.status.statusCode.value = StatusCode.REQUESTER_URI 
    1106             samlResponse.status.statusMessage="Issuer format is not recognised" 
     1117            samlResponse.status.statusMessage.value = \ 
     1118                                            "Issuer format is not recognised" 
    11071119            return samlResponse 
    11081120         
     
    11211133            samlResponse.status.statusCode.value = \ 
    11221134                                        StatusCode.UNKNOWN_PRINCIPAL_URI 
     1135            samlResponse.status.statusMessage.value = str(e) 
    11231136            return samlResponse 
    11241137             
     
    11261139            log.exception(e) 
    11271140            samlResponse.status.statusCode.value = StatusCode.REQUEST_DENIED_URI 
     1141            samlResponse.status.statusMessage.value = str(e) 
    11281142            return samlResponse 
    11291143             
     
    11321146            samlResponse.status.statusCode.value = \ 
    11331147                                        StatusCode.INVALID_ATTR_NAME_VALUE_URI 
     1148            samlResponse.status.statusMessage.value = str(e) 
    11341149            return samlResponse 
    11351150             
     
    11381153            samlResponse.status.statusCode.value = \ 
    11391154                                        StatusCode.INVALID_ATTR_NAME_VALUE_URI 
     1155            samlResponse.status.statusMessage.value = str(e) 
    11401156            return samlResponse 
    11411157             
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/wsgi/attributeauthority.py

    r5678 r5738  
    7979         
    8080        self.aa = AttributeAuthority.fromProperties(propPrefix=prefix, 
    81                                                    **app_conf) 
     81                                                    **app_conf) 
    8282        self.attributeQuery = self.aa.samlAttributeQueryFactory() 
    8383 
  • TI12-security/trunk/python/ndg_security_server/ndg/security/server/zsi/attributeauthority/__init__.py

    r5678 r5738  
    11"""ZSI Server side SOAP Binding for Attribute Authority Web Service 
    22 
    3 NERC Data Grid Project""" 
     3NERC DataGrid Project""" 
    44__author__ = "P J Kershaw" 
    55__date__ = "11/06/08" 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/config/attributeauthority/sitea/site-a.ini

    r5678 r5738  
    5757attributeAuthority.attCertNotBeforeOff: 0 
    5858 
     59# Clock skew for SAML Attribute Queries - allow clockSkew number of seconds 
     60# tolerance for notBefore and notOnOrAfter parameters. Set here to 3 minutes 
     61attributeAuthority.clockSkew: 180.0 
     62 
    5963# All Attribute Certificates issued are recorded in this dir 
    6064attributeAuthority.attCertDir: %(here)s/attributeCertificateLog 
     
    103107prefix = saml.soapbinding. 
    104108 
    105 saml.soapbinding.pathMatchList = /attributeauthority/saml 
     109saml.soapbinding.pathMatchList = /AttributeAuthority/saml 
    106110saml.soapbinding.queryInterfaceKeyName = %(attributeQueryInterfaceEnvironKeyName)s 
    107111 
     
    172176[logger_ndg] 
    173177level = DEBUG 
    174 handlers = 
     178handlers =  
    175179qualname = ndg 
    176180 
     
    182186 
    183187[formatter_generic] 
    184 format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s 
    185 datefmt = %H:%M:%S 
     188format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s 
     189datefmt = %Y/%m/%d %H:%M:%S 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/config/attributeauthority/sitea/siteAServerApp.py

    r5290 r5738  
    1414 
    1515def infoApp(environ, start_response): 
    16     start_response('200 OK', [('Content-type', 'text/plain')]) 
    17     return "NDG Security Attribute Authority Unit Tests: Site A Server" 
     16    response = "NDG Security Attribute Authority Unit Tests: Site A Server" 
     17    start_response('200 OK', [('Content-type', 'text/plain'), 
     18                              ('Content-length', str(len(response)))]) 
     19    return [response] 
    1820 
    1921def app_factory(global_config, **local_conf): 
     
    3335    import sys 
    3436    import logging 
    35     logging.basicConfig(level=logging.DEBUG) 
     37#    logging.basicConfig(level=logging.DEBUG) 
    3638 
    3739    if len(sys.argv) > 1: 
     
    4446    from paste.httpserver import serve 
    4547    from paste.deploy import loadapp 
    46  
     48    from paste.script.util.logging_config import fileConfig 
     49     
     50    fileConfig(cfgFilePath) 
    4751    app = loadapp('config:%s' % cfgFilePath) 
    4852    serve(app, host='0.0.0.0', port=port) 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/config/attributeauthority/siteb/siteBServerApp.py

    r5290 r5738  
    1414 
    1515def infoApp(environ, start_response): 
    16     start_response('200 OK', [('Content-type', 'text/plain')]) 
    17     return "NDG Security Attribute Authority Unit Tests: Site B Server" 
     16    response = "NDG Security Attribute Authority Unit Tests: Site B Server" 
     17    start_response('200 OK', [('Content-type', 'text/plain'), 
     18                              ('Content-length', str(len(response)))]) 
     19    return [response] 
    1820 
    1921def app_factory(global_config, **local_conf): 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/integration/authz_lite/securityservices.ini

    r5733 r5738  
    210210attributeAuthority.environKeyName = %(attributeAuthorityEnvironKeyName)s 
    211211 
     212# Key name for the SAML SOAP binding based interface to reference this 
     213# service's attribute query method 
     214attributeAuthority.environKeyNameAttributeQueryInterface: %(attributeQueryInterfaceEnvironKeyName)s 
     215 
    212216# Attribute Authority settings 
    213217# 'name' setting MUST agree with map config file 'thisHost' name attribute 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/attributeauthorityclient/attAuthorityClientTest.cfg

    r5703 r5738  
    4848userAttCertFilePathList = $NDGSEC_AACLNT_UNITTEST_DIR/ac-clnt.xml 
    4949 
    50 [test10SAMLAttributeQuery] 
    51 uri = http://localhost:5000/attributeauthority/saml 
     50# SAML Interface use a separate test case class in the test module and is  
     51# included here 
     52[test01SAMLAttributeQuery] 
     53uri = http://localhost:5000/AttributeAuthority/saml 
     54subject = https://openid.localhost/philip.kershaw 
     55siteAttributeName = urn:siteA:security:authz:1.0:attr 
    5256 
    53 [test11SAMLAttributeQueryInvalidIssuer] 
    54 uri = http://localhost:5000/attributeauthority/saml 
     57[test02SAMLAttributeQueryInvalidIssuer] 
     58uri = http://localhost:5000/AttributeAuthority/saml 
     59subject = https://openid.localhost/philip.kershaw 
     60siteAttributeName = urn:siteA:security:authz:1.0:attr 
    5561 
    56 [test12SAMLAttributeQueryUnknownSubject] 
    57 uri = http://localhost:5000/attributeauthority/saml 
     62[test03SAMLAttributeQueryUnknownSubject] 
     63uri = http://localhost:5000/AttributeAuthority/saml 
     64subject = https://openid.localhost/unknown 
     65siteAttributeName = urn:siteA:security:authz:1.0:attr 
    5866 
    59 [test13SAMLAttributeQueryInvalidAttrName] 
    60 uri = http://localhost:5000/attributeauthority/saml 
     67[test04SAMLAttributeQueryInvalidAttrName] 
     68uri = http://localhost:5000/AttributeAuthority/saml 
     69subject = https://openid.localhost/philip.kershaw 
     70siteAttributeName = invalid-attr 
    6171 
    6272[wsse] 
  • TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/attributeauthorityclient/test_attributeauthorityclient.py

    r5703 r5738  
    4444from ndg.security.common.saml.bindings import SOAPBinding as SamlSoapBinding 
    4545 
    46  
    47 class AttributeAuthorityClientTestCase(BaseTestCase): 
     46class AttributeAuthorityClientBaseTestCase(BaseTestCase): 
     47    def __init__(self, *arg, **kw): 
     48        super(AttributeAuthorityClientBaseTestCase, self).__init__(*arg, **kw) 
     49 
     50        if 'NDGSEC_AACLNT_UNITTEST_DIR' not in os.environ: 
     51            os.environ['NDGSEC_AACLNT_UNITTEST_DIR'] = \ 
     52                os.path.abspath(os.path.dirname(__file__)) 
     53 
     54        self.cfgParser = CaseSensitiveConfigParser() 
     55        cfgFilePath = jnPath(os.environ['NDGSEC_AACLNT_UNITTEST_DIR'], 
     56                             'attAuthorityClientTest.cfg') 
     57        self.cfgParser.read(cfgFilePath) 
     58         
     59        self.cfg = {} 
     60        for section in self.cfgParser.sections(): 
     61            self.cfg[section] = dict(self.cfgParser.items(section)) 
     62 
     63        try: 
     64            self.sslCACertList = [X509CertRead(xpdVars(caFile)) for caFile in \ 
     65                         self.cfg['setUp']['sslcaCertFilePathList'].split()] 
     66        except KeyError: 
     67            self.sslCACertList = [] 
     68 
     69       
     70class AttributeAuthorityClientTestCase(AttributeAuthorityClientBaseTestCase): 
    4871    clntPriKeyPwd = None 
    4972    pemPat = "-----BEGIN CERTIFICATE-----[^\-]*-----END CERTIFICATE-----" 
     
    6689        return signingCertChain 
    6790 
    68  
    6991    def setUp(self): 
    7092        super(AttributeAuthorityClientTestCase, self).setUp() 
    71          
     93                 
    7294        if 'NDGSEC_INT_DEBUG' in os.environ: 
    7395            import pdb 
    7496            pdb.set_trace() 
    75          
    76         if 'NDGSEC_AACLNT_UNITTEST_DIR' not in os.environ: 
    77             os.environ['NDGSEC_AACLNT_UNITTEST_DIR'] = \ 
    78                 os.path.abspath(os.path.dirname(__file__)) 
    79  
    80         self.cfgParser = CaseSensitiveConfigParser() 
    81         cfgFilePath = jnPath(os.environ['NDGSEC_AACLNT_UNITTEST_DIR'], 
    82                              'attAuthorityClientTest.cfg') 
    83         self.cfgParser.read(cfgFilePath) 
    84          
    85         self.cfg = {} 
    86         for section in self.cfgParser.sections(): 
    87             self.cfg[section] = dict(self.cfgParser.items(section)) 
    88  
    89         try: 
    90             sslCACertList = [X509CertRead(xpdVars(file)) for file in \ 
    91                          self.cfg['setUp']['sslcaCertFilePathList'].split()] 
    92         except KeyError: 
    93             sslCACertList = [] 
    9497             
    9598        thisSection = self.cfg['setUp'] 
     
    98101        self.siteAClnt = AttributeAuthorityClient(uri=thisSection['uri'], 
    99102                                sslPeerCertCN=thisSection.get('sslPeerCertCN'), 
    100                                 sslCACertList=sslCACertList, 
     103                                sslCACertList=self.sslCACertList, 
    101104                                cfgFileSection='wsse', 
    102105                                cfg=self.cfgParser)             
     
    296299                msgFile = open(outFilePfx+".msg", 'w') 
    297300                msgFile.write('Failed for "%s": %s\n' % (acFilePath, e)) 
    298               
    299     def test10SAMLAttributeQuery(self): 
    300         _cfg = self.cfg['test10SAMLAttributeQuery'] 
     301 
     302    
     303class AttributeAuthoritySAMLInterfaceTestCase( 
     304                                        AttributeAuthorityClientBaseTestCase): 
     305    """Separate class for Attribute Authority SAML Attribute Query interface""" 
     306            
     307    def test01SAMLAttributeQuery(self): 
     308        _cfg = self.cfg['test01SAMLAttributeQuery'] 
    301309         
    302310        attributeQuery = AttributeQuery() 
     
    312320        attributeQuery.subject.nameID = NameID() 
    313321        attributeQuery.subject.nameID.format = "urn:esg:openid" 
    314         attributeQuery.subject.nameID.value = \ 
    315                                     "https://openid.localhost/philip.kershaw" 
     322        attributeQuery.subject.nameID.value = _cfg['subject'] 
    316323        xsStringNs = SAMLConstants.XSD_NS+"#"+\ 
    317324                                        XSStringAttributeValue.TYPE_LOCAL_NAME 
     
    338345 
    339346        siteAAttribute = Attribute() 
    340         siteAAttribute.name = "urn:siteA:security:authz:1.0:attr" 
     347        siteAAttribute.name = _cfg['siteAttributeName'] 
    341348        siteAAttribute.nameFormat = xsStringNs 
    342349         
     
    363370        print("Pretty print SAML Response ...") 
    364371        print(prettyPrint(samlResponseElem)) 
    365  
    366372              
    367     def test11SAMLAttributeQueryInvalidIssuer(self): 
    368         _cfg = self.cfg['test11SAMLAttributeQueryInvalidIssuer'] 
     373    def test02SAMLAttributeQueryInvalidIssuer(self): 
     374        _cfg = self.cfg['test02SAMLAttributeQueryInvalidIssuer'] 
    369375         
    370376        attributeQuery = AttributeQuery() 
     
    380386        attributeQuery.subject.nameID = NameID() 
    381387        attributeQuery.subject.nameID.format = "urn:esg:openid" 
    382         attributeQuery.subject.nameID.value = \ 
    383                                     "https://openid.localhost/philip.kershaw" 
     388        attributeQuery.subject.nameID.value = _cfg['subject'] 
    384389        xsStringNs = SAMLConstants.XSD_NS+"#"+\ 
    385390                                        XSStringAttributeValue.TYPE_LOCAL_NAME 
    386391 
    387392        siteAAttribute = Attribute() 
    388         siteAAttribute.name = "urn:siteA:security:authz:1.0:attr" 
     393        siteAAttribute.name = _cfg['siteAttributeName'] 
    389394        siteAAttribute.nameFormat = xsStringNs 
    390395         
     
    403408        print(prettyPrint(samlResponseElem)) 
    404409                     
    405     def test12SAMLAttributeQueryUnknownSubject(self): 
    406         _cfg = self.cfg['test12SAMLAttributeQueryUnknownSubject'] 
     410    def test03SAMLAttributeQueryUnknownSubject(self): 
     411        _cfg = self.cfg['test03SAMLAttributeQueryUnknownSubject'] 
    407412         
    408413        attributeQuery = AttributeQuery() 
     
    418423        attributeQuery.subject.nameID = NameID() 
    419424        attributeQuery.subject.nameID.format = "urn:esg:openid" 
    420         attributeQuery.subject.nameID.value = \ 
    421                                     "https://openid.localhost/unknown" 
     425        attributeQuery.subject.nameID.value = _cfg['subject'] 
    422426        xsStringNs = SAMLConstants.XSD_NS+"#"+\ 
    423427                                        XSStringAttributeValue.TYPE_LOCAL_NAME 
    424428 
    425429        siteAAttribute = Attribute() 
    426         siteAAttribute.name = "urn:siteA:security:authz:1.0:attr" 
     430        siteAAttribute.name = _cfg['siteAttributeName'] 
    427431        siteAAttribute.nameFormat = xsStringNs 
    428432         
     
    441445        print(prettyPrint(samlResponseElem)) 
    442446              
    443     def test13SAMLAttributeQueryInvalidAttrName(self): 
    444         _cfg = self.cfg['test13SAMLAttributeQueryInvalidAttrName'] 
     447    def test04SAMLAttributeQueryInvalidAttrName(self): 
     448        _cfg = self.cfg['test04SAMLAttributeQueryInvalidAttrName'] 
    445449         
    446450        attributeQuery = AttributeQuery() 
     
    456460        attributeQuery.subject.nameID = NameID() 
    457461        attributeQuery.subject.nameID.format = "urn:esg:openid" 
    458         attributeQuery.subject.nameID.value = \ 
    459                                     "https://openid.localhost/philip.kershaw" 
     462        attributeQuery.subject.nameID.value = _cfg['subject'] 
    460463        xsStringNs = SAMLConstants.XSD_NS+"#"+\ 
    461464                                        XSStringAttributeValue.TYPE_LOCAL_NAME 
Note: See TracChangeset for help on using the changeset viewer.