def fromXML(cls, elem):
        """Parse ElementTree element into a SAML XACMLAuthzDecisionQuery object
        
        @type elem: ElementTree.Element
        @param elem: XML element containing the AuthzDecisionQuery
        @rtype: saml.saml2.core.AuthzDecisionQuery
        @return: AuthzDecisionQuery object
        """
        if not ElementTree.iselement(elem):
            raise TypeError("Expecting %r input type for parsing; got %r" %
                            (ElementTree.Element, elem))

        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME:
            raise XMLTypeParseError("No \"%s\" element found" %
                                    cls.DEFAULT_ELEMENT_LOCAL_NAME)
        
        # Unpack attributes from top-level element
        attributeValues = []
        for attributeName in (cls.VERSION_ATTRIB_NAME,
                              cls.ISSUE_INSTANT_ATTRIB_NAME,
                              cls.ID_ATTRIB_NAME):
            attributeValue = elem.attrib.get(attributeName)
            if attributeValue is None:
                raise XMLTypeParseError('No "%s" attribute found in "%s" '
                                 'element' %
                                 (attributeName,
                                  cls.DEFAULT_ELEMENT_LOCAL_NAME))
                
            attributeValues.append(attributeValue)
        
        authzDecisionQuery = XACMLAuthzDecisionQuery()
        authzDecisionQuery.version = SAMLVersion(attributeValues[0])
        if authzDecisionQuery.version != SAMLVersion.VERSION_20:
            raise NotImplementedError("Parsing for %r is implemented for "
                                      "SAML version %s only; version %s is " 
                                      "not supported" % 
                                      (cls,
                                       SAMLVersion(SAMLVersion.VERSION_20),
                                       SAMLVersion(authzDecisionQuery.version)))
            
        authzDecisionQuery.issueInstant = SAMLDateTime.fromString(
                                                            attributeValues[1])
        authzDecisionQuery.id = attributeValues[2]
        
        for childElem in elem:
            localName = QName.getLocalPart(childElem.tag)
            if localName == Issuer.DEFAULT_ELEMENT_LOCAL_NAME:
                # Parse Issuer
                authzDecisionQuery.issuer = IssuerElementTree.fromXML(childElem)

            elif localName == Request.ELEMENT_LOCAL_NAME:
                # Create XACML context request from Request element.
                authzDecisionQuery.xacmlContextRequest = \
                    RequestElementTree.fromXML(childElem)

            else:
                raise XMLTypeParseError("Unrecognised XACMLAuthzDecisionQuery child "
                                        "element \"%s\"" % localName)
        
        return authzDecisionQuery
    def fromXML(cls, elem):
        if not ElementTree.iselement(elem):
            raise TypeError("Expecting %r input type for parsing; got %r" %
                            (ElementTree.Element, elem))

        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME:
            raise XMLTypeParseError("No \"%s\" element found" %
                                    cls.DEFAULT_ELEMENT_LOCAL_NAME)

        authzDecisionStatement = XACMLAuthzDecisionStatement()

        for childElem in elem:
            localName = QName.getLocalPart(childElem.tag)
            if localName == Response.ELEMENT_LOCAL_NAME:
                # Create XACML context request from Response element.
                authzDecisionStatement.xacmlContextResponse = \
                    ResponseElementTree.fromXML(childElem)

            elif localName == Request.ELEMENT_LOCAL_NAME:
                # Create XACML context request from Request element.
                authzDecisionStatement.xacmlContextRequest = \
                    RequestElementTree.fromXML(childElem)

            else:
                raise XMLTypeParseError("Unrecognised XACMLAuthzDecisionQuery child "
                                        "element \"%s\"" % localName)

        return authzDecisionStatement
Beispiel #3
0
    def fromXML(cls, elem):
        """Parse ElementTree ESG Group/Role attribute element into a SAML 
        ESGFGroupRoleAttributeValue object
        
        @type elem: ElementTree.Element
        @param elem: Attribute value as ElementTree XML element
        @rtype: saml.saml2.core.ESGFGroupRoleAttributeValue
        @return: SAML ESG Group/Role Attribute value
        """
        
        # Update namespace map for the Group/Role type referenced.  
        if not Config.use_lxml:
            ElementTree._namespace_map[cls.DEFAULT_NS] = cls.DEFAULT_PREFIX
        
        if not ElementTree.iselement(elem):
            raise TypeError("Expecting %r input type for parsing; got %r" %
                            (ElementTree.Element, elem))

        localName = QName.getLocalPart(elem.tag)
        if localName != cls.DEFAULT_ELEMENT_LOCAL_NAME:
            raise XMLTypeParseError("No \"%s\" element found" %
                                    cls.DEFAULT_ELEMENT_LOCAL_NAME)
                                   
        # Check for group/role child element
        if len(elem) == 0:
            raise XMLTypeParseError('Expecting "%s" child element to "%s" '
                                    'element' % (cls.TYPE_LOCAL_NAME,
                                               cls.DEFAULT_ELEMENT_LOCAL_NAME))
        
        childElem = elem[0]
        childLocalName = QName.getLocalPart(childElem.tag)
        if childLocalName != cls.TYPE_LOCAL_NAME:
            raise XMLTypeParseError("No \"%s\" element found" %
                                    cls.TYPE_LOCAL_NAME)

                                      
        attributeValue = ESGFGroupRoleAttributeValue()
        groupName = childElem.attrib.get(cls.GROUP_ATTRIB_NAME)
        if groupName is None:
            raise XMLTypeParseError('No "%s" attribute found in Group/Role '
                                    'attribute element' % 
                                    cls.GROUP_ATTRIB_NAME)
        attributeValue.group = groupName
        
        roleName = childElem.attrib.get(cls.ROLE_ATTRIB_NAME)
        if roleName is None:
            roleName = cls.DEFAULT_ROLE_NAME
            
        attributeValue.role = roleName

        return attributeValue
Beispiel #4
0
    def factoryMatchFunc(cls, elem):
        """Match function used by AttributeValueElementTreeFactory to
        determine whether the given attribute is ESGFGroupRoleAttributeValue
        type
        
        @type elem: ElementTree.Element
        @param elem: Attribute value as ElementTree XML element
        @rtype: ndg.security.common.saml_utils.etree.ESGFGroupRoleAttributeValue
        or None
        @return: SAML ESGF Group/Role Attribute Value class if elem is an
        Group/role type element or None if if doesn't match this type 
        """
        
        # Group/role element is a child of the AttributeValue element
        if len(elem) == 0:
            return None
        
        childLocalName = QName.getLocalPart(elem[0].tag)
        if childLocalName != cls.TYPE_LOCAL_NAME:
            raise XMLTypeParseError('No "%s" child element found in '
                                    'AttributeValue' % cls.TYPE_LOCAL_NAME)
               
        if cls.GROUP_ATTRIB_NAME in elem[0].attrib and \
           cls.ROLE_ATTRIB_NAME in elem[0].attrib:
            return cls

        return None
    def __call__(self, environ, start_response):
        """Check for and parse a SOAP SAML Attribute Query and return a
        SAML Response
        
        :type environ: dict
        :param environ: WSGI environment variables dictionary
        :type start_response: function
        :param start_response: standard WSGI start response function
        """
    
        # Ignore non-matching path
        if environ['PATH_INFO'] not in (self.mountPath, self.mountPath + '/'):
            return self._app(environ, start_response)
          
        # Ignore non-POST requests
        if environ.get('REQUEST_METHOD') != 'POST':
            return self._app(environ, start_response)
        
        soapRequestStream = environ.get('wsgi.input')
        if soapRequestStream is None:
            raise SOAPQueryInterfaceMiddlewareError('No "wsgi.input" in '
                                                    'environ')
        
        # TODO: allow for chunked data
        contentLength = environ.get('CONTENT_LENGTH')
        if contentLength is None:
            raise SOAPQueryInterfaceMiddlewareError('No "CONTENT_LENGTH" in '
                                                    'environ')

        contentLength = int(contentLength)
        if contentLength <= 0:
            raise SOAPQueryInterfaceMiddlewareError('"CONTENT_LENGTH" in '
                                                    'environ is %d' %
                                                    contentLength)
            
        soapRequestTxt = soapRequestStream.read(contentLength)
        
        # Parse into a SOAP envelope object
        soapRequest = SOAPEnvelope()
        soapRequest.parse(StringIO(soapRequestTxt))
        
        log.debug("SOAPQueryInterfaceMiddleware.__call__: received SAML "
                  "SOAP Query: %s", soapRequestTxt)
       
        queryElem = soapRequest.body.elem[0]
        
        # Create a response with basic attributes if provided in the 
        # initialisation config
        samlResponse = self._initResponse()
        
        try:
            queryType = QName.getLocalPart(queryElem.tag)
            if queryType == XACMLAuthzDecisionQuery.DEFAULT_ELEMENT_LOCAL_NAME:
                # Set up additional ElementTree parsing for XACML profile.
                etree_xacml_profile.setElementTreeMap()
                samlQuery = self.deserialiseXacmlProfile(queryElem)
            else:
                samlQuery = self.deserialise(queryElem)

        except UnknownAttrProfile, e:
            log.exception("%r raised parsing incoming query: %s" % 
                          (type(e), traceback.format_exc()))
            samlResponse.status.statusCode.value = \
                                            StatusCode.UNKNOWN_ATTR_PROFILE_URI