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
Esempio n. 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
Esempio n. 4
0
    def toXML(cls, attributeValue):
        """Create an XML representation of the input SAML ESG Group/Role type
        Attribute Value
        
        @type attributeValue: ndg.security.common.saml_utils.esgf.ESGFGroupRoleAttributeValue
        @param attributeValue: Group/Role Attribute Value to be represented as 
        an ElementTree Element
        @rtype: ElementTree.Element
        @return: ElementTree Element
        """
        elem = AttributeValueElementTreeBase.toXML(attributeValue)
        
        if not isinstance(attributeValue, ESGFGroupRoleAttributeValue):
            raise TypeError("Expecting %r type; got: %r" % 
                            (ESGFGroupRoleAttributeValue, type(attributeValue)))
            
        if not Config.use_lxml:
            ElementTree._namespace_map[attributeValue.namespaceURI
                                       ] = attributeValue.namespacePrefix
                                   
        tag = str(QName.fromGeneric(cls.TYPE_NAME))    
        groupRoleElem = etree.makeEtreeElement(tag,
                                        cls.DEFAULT_ELEMENT_NAME.prefix,
                                        cls.DEFAULT_ELEMENT_NAME.namespaceURI)
        
        groupRoleElem.set(cls.GROUP_ATTRIB_NAME, attributeValue.group)
        groupRoleElem.set(cls.ROLE_ATTRIB_NAME, attributeValue.role)

        elem.append(groupRoleElem)
        
        return elem
Esempio n. 5
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 toXML(cls, xacmlAuthzDecisionStatement):
        if not isinstance(xacmlAuthzDecisionStatement,
                          XACMLAuthzDecisionStatement):
            raise TypeError("Expecting %r class got %r" %
                            (XACMLAuthzDecisionStatement, 
                            type(xacmlAuthzDecisionStatement)))

        if not xacmlAuthzDecisionStatement.xacmlContextResponse:
            raise AttributeError("No xacmlContextResponse has been set for the "
                                 "XACMLAuthzDecisionStatement")

        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME))
        elem = etree.makeEtreeElement(tag, cls.DEFAULT_ELEMENT_NAME.prefix,
                                      cls.DEFAULT_ELEMENT_NAME.namespaceURI)

        xacmlContextResponseElem = ResponseElementTree.toXML(
                            xacmlAuthzDecisionStatement.xacmlContextResponse)
        elem.append(xacmlContextResponseElem)

        if xacmlAuthzDecisionStatement.xacmlContextRequest:
            xacmlContextRequestElem = RequestElementTree.toXML(
                                xacmlAuthzDecisionStatement.xacmlContextRequest)
            elem.append(xacmlContextRequestElem)

        return elem
Esempio n. 7
0
    def _make_xacml_context_request(cls,
                                    httpMethod,
                                    resourceURI,
                                    resourceContents,
                                    subjectID,
                                    subjectIdFormat,
                                    actions=None):
        """Create a XACML Request. Include post data as resource content if the
        HTTP method is POST.
        :type httpMethod: str
        :param httpMethod: HTTP method
        :type resourceURI: str
        :param resourceURI: resource URI
        :type resourceContents: basestr
        :param resourceContents: resource contents XML as string
        :type subjectID: str
        :param subjectID: subject ID
        :type subjectIdFormat: str
        :param subjectIdFormat: subject ID format
        :type actions: list of str
        :param actions: actions
        """
        if actions is None:
            actions = []

        if httpMethod == 'GET':
            ### TODO Should action be related to HTTP method?
            return cls._createXacmlProfileRequestCtx(subjectIdFormat,
                                                     subjectID, resourceURI,
                                                     None, actions)

        elif httpMethod == 'POST':
            resourceContentsElem = ElementTree.XML(resourceContents)
            tag = str(
                QName(XacmlContextBase.XACML_2_0_CONTEXT_NS,
                      XacmlResource.RESOURCE_CONTENT_ELEMENT_LOCAL_NAME))
            resourceContent = etree.makeEtreeElement(
                tag, XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX,
                XacmlContextBase.XACML_2_0_CONTEXT_NS)
            resourceContent.append(resourceContentsElem)

            request = cls._createXacmlProfileRequestCtx(
                subjectIdFormat, subjectID, resourceURI, resourceContent,
                actions)

            return request
    def toXML(cls, xacmlAuthzDecisionQuery):
        """Create an XML representation of the input SAML Authorization
        Decision Query object

        @type xacmlAuthzDecisionQuery: saml.saml2.core.AuthzDecisionQuery
        @param xacmlAuthzDecisionQuery: SAML Authorization Decision Query
        @rtype: ElementTree.Element
        @return: Attribute Query as ElementTree XML element
        """
        if not isinstance(xacmlAuthzDecisionQuery, XACMLAuthzDecisionQuery):
            raise TypeError("Expecting %r class got %r" % (XACMLAuthzDecisionQuery, 
                                                    type(xacmlAuthzDecisionQuery)))

        if not xacmlAuthzDecisionQuery.xacmlContextRequest:
            raise AttributeError("No xacmlContextRequest has been set for the "
                                 "XACMLAuthzDecisionQuery")

        issueInstant = SAMLDateTime.toString(xacmlAuthzDecisionQuery.issueInstant)
        attrib = {
            cls.ID_ATTRIB_NAME: xacmlAuthzDecisionQuery.id,
            cls.ISSUE_INSTANT_ATTRIB_NAME: issueInstant,

            # Nb. Version is a SAMLVersion instance and requires explicit cast
            cls.VERSION_ATTRIB_NAME: str(xacmlAuthzDecisionQuery.version),
        }

        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME))
        elem = etree.makeEtreeElement(tag, cls.DEFAULT_ELEMENT_NAME.prefix,
                                      cls.DEFAULT_ELEMENT_NAME.namespaceURI,
                                      **attrib)

        issuerElem = IssuerElementTree.toXML(xacmlAuthzDecisionQuery.issuer)
        elem.append(issuerElem)

        requestElem = RequestElementTree.toXML(
                                    xacmlAuthzDecisionQuery.xacmlContextRequest)
        elem.append(requestElem)

        return elem
Esempio n. 9
0
    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