source: TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/saml_utils/esg/xml/etree.py @ 7287

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/saml_utils/esg/xml/etree.py@7287
Revision 7287, 6.7 KB checked in by pjkersha, 10 years ago (diff)

Incomplete - task 2: XACML-Security Integration

  • Working WSGI Authorisation filter with connection to SAML/XACML based Authorisation Service - unit tests: ndg.security.test.unit.wsgi.authz.test_authz
  • It may need some optimisation to avoid too many WS callouts to the Authorisation Service - perhaps add a local PDP to the authorisation filter to filter out some requests going over the wire e.g. requests for web page CSS or graphics content.
  • The XACML policy file has some big additions to it to support the various test conditions in ndg.security.test.unit.wsgi.authz.test_authz. These should be ported back to the ndg_xacml package unit tests.
  • Next major task: remove temp fix in XACML Context handler - instead of using hardwired roles for the user alter it so that the PDP makes a request back to the PIP (Policy Enforcement Point) to grab additional attributes. The PIP will call to Attibute Service(s) to pull any additional attributes needed/
  • Property svn:keywords set to Id
Line 
1"""SAML 2.0 Earth System Grid Group/Role ElementTree representation
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "09/11/09"
7__copyright__ = "(C) 2009 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11import logging
12log = logging.getLogger(__name__)
13
14from xml.etree import ElementTree
15
16from ndg.saml.xml import XMLTypeParseError, UnknownAttrProfile
17from ndg.saml.xml.etree import (AttributeValueElementTreeBase, 
18                                ResponseElementTree,
19                                QName)
20
21from ndg.security.common.saml_utils.esg import XSGroupRoleAttributeValue
22
23
24class XSGroupRoleAttributeValueElementTree(AttributeValueElementTreeBase,
25                                           XSGroupRoleAttributeValue):
26    """ElementTree XML representation of Earth System Grid custom Group/Role
27    Attribute Value""" 
28
29    @classmethod
30    def toXML(cls, attributeValue):
31        """Create an XML representation of the input SAML ESG Group/Role type
32        Attribute Value
33       
34        @type assertion: saml.saml2.core.XSGroupRoleAttributeValue
35        @param assertion: XSGroupRoleAttributeValue to be represented as an
36        ElementTree Element
37        @rtype: ElementTree.Element
38        @return: ElementTree Element
39        """
40        elem = AttributeValueElementTreeBase.toXML(attributeValue)
41       
42        if not isinstance(attributeValue, XSGroupRoleAttributeValue):
43            raise TypeError("Expecting %r type; got: %r" % 
44                            (XSGroupRoleAttributeValue, type(attributeValue)))
45           
46        ElementTree._namespace_map[attributeValue.namespaceURI
47                                   ] = attributeValue.namespacePrefix
48                                   
49        tag = str(QName.fromGeneric(cls.TYPE_NAME))   
50        groupRoleElem = ElementTree.Element(tag)
51        ElementTree._namespace_map[cls.DEFAULT_ELEMENT_NAME.namespaceURI
52                                   ] = cls.DEFAULT_ELEMENT_NAME.prefix
53       
54        groupRoleElem.set(cls.GROUP_ATTRIB_NAME, attributeValue.group)
55        groupRoleElem.set(cls.ROLE_ATTRIB_NAME, attributeValue.role)
56
57        elem.append(groupRoleElem)
58       
59        return elem
60
61    @classmethod
62    def fromXML(cls, elem):
63        """Parse ElementTree ESG Group/Role attribute element into a SAML
64        XSGroupRoleAttributeValue object
65       
66        @type elem: ElementTree.Element
67        @param elem: Attribute value as ElementTree XML element
68        @rtype: saml.saml2.core.XSGroupRoleAttributeValue
69        @return: SAML ESG Group/Role Attribute value
70        """
71       
72        # Update namespace map for the Group/Role type referenced. 
73        ElementTree._namespace_map[cls.DEFAULT_NS] = cls.DEFAULT_PREFIX
74       
75        if not ElementTree.iselement(elem):
76            raise TypeError("Expecting %r input type for parsing; got %r" %
77                            (ElementTree.Element, elem))
78
79        localName = QName.getLocalPart(elem.tag)
80        if localName != cls.DEFAULT_ELEMENT_LOCAL_NAME:
81            raise XMLTypeParseError("No \"%s\" element found" %
82                                    cls.DEFAULT_ELEMENT_LOCAL_NAME)
83                                   
84        # Check for group/role child element
85        if len(elem) == 0:
86            raise XMLTypeParseError('Expecting "%s" child element to "%s" '
87                                    'element' % (cls.TYPE_LOCAL_NAME,
88                                               cls.DEFAULT_ELEMENT_LOCAL_NAME))
89       
90        childElem = elem[0]
91        childLocalName = QName.getLocalPart(childElem.tag)
92        if childLocalName != cls.TYPE_LOCAL_NAME:
93            raise XMLTypeParseError("No \"%s\" element found" %
94                                    cls.TYPE_LOCAL_NAME)
95
96                                     
97        attributeValue = XSGroupRoleAttributeValue()
98        groupName = childElem.attrib.get(cls.GROUP_ATTRIB_NAME)
99        if groupName is None:
100            raise XMLTypeParseError('No "%s" attribute found in Group/Role '
101                                    'attribute element' % 
102                                    cls.GROUP_ATTRIB_NAME)
103        attributeValue.group = groupName
104       
105        roleName = childElem.attrib.get(cls.ROLE_ATTRIB_NAME)
106        if roleName is None:
107            raise XMLTypeParseError('No "%s" attribute found in Group/Role '
108                                    'attribute element' % 
109                                    cls.GROUP_ATTRIB_NAME)
110        attributeValue.role = roleName
111
112        return attributeValue
113   
114    @classmethod
115    def factoryMatchFunc(cls, elem):
116        """Match function used by AttributeValueElementTreeFactory to
117        determine whether the given attribute is XSGroupRole type
118       
119        @type elem: ElementTree.Element
120        @param elem: Attribute value as ElementTree XML element
121        @rtype: saml.saml2.core.XSGroupRoleAttributeValue or None
122        @return: SAML ESG Group/Role Attribute Value class if elem is an
123        Group/role type element or None if if doesn't match this type
124        """
125       
126        # Group/role element is a child of the AttributeValue element
127        if len(elem) == 0:
128            return None
129       
130        childLocalName = QName.getLocalPart(elem[0].tag)
131        if childLocalName != cls.TYPE_LOCAL_NAME:
132            raise XMLTypeParseError('No "%s" child element found in '
133                                    'AttributeValue' % cls.TYPE_LOCAL_NAME)
134               
135        if cls.GROUP_ATTRIB_NAME in elem[0].attrib and \
136           cls.ROLE_ATTRIB_NAME in elem[0].attrib:
137            return cls
138
139        return None
140
141
142class EsgResponseElementTree(ResponseElementTree):
143    """Extend ResponseElementTree type for Attribute Query Response to include
144    ESG custom Group/Role Attribute support"""
145   
146    @classmethod
147    def toXML(cls, response, **kw):
148        # Add mapping for ESG Group/Role Attribute Value to enable ElementTree
149        # Attribute Value factory to render the XML output
150        toXMLTypeMap = kw.get('customToXMLTypeMap', {})
151        toXMLTypeMap[XSGroupRoleAttributeValue
152                     ] = XSGroupRoleAttributeValueElementTree
153       
154        kw['customToXMLTypeMap'] = toXMLTypeMap
155       
156        # Convert to ElementTree representation to enable attachment to SOAP
157        # response body
158        return ResponseElementTree.toXML(response, **kw)
159   
160    @classmethod
161    def fromXML(cls, elem, **kw):
162        toSAMLTypeMap = kw.get('customToSAMLTypeMap', [])
163        toSAMLTypeMap.append(
164                        XSGroupRoleAttributeValueElementTree.factoryMatchFunc)
165        kw['customToSAMLTypeMap'] = toSAMLTypeMap
166       
167        return ResponseElementTree.fromXML(elem, **kw)
Note: See TracBrowser for help on using the repository browser.