1 """NDG XACML ElementTree based generic reader for subject, resource, action and
2 environment match types
3
4 NERC DataGrid
5 """
6 __author__ = "P J Kershaw"
7 __date__ = "16/03/10"
8 __copyright__ = "(C) 2010 Science and Technology Facilities Council"
9 __contact__ = "Philip.Kershaw@stfc.ac.uk"
10 __license__ = "BSD - see LICENSE file in top-level directory"
11 __contact__ = "Philip.Kershaw@stfc.ac.uk"
12 __revision__ = "$Id: matchreader.py 8028 2012-02-27 14:38:01Z rwilkinson $"
13 from ndg.xacml.core.attributevalue import AttributeValue
14 from ndg.xacml.core.attributeselector import AttributeSelector
15 from ndg.xacml.parsers import XMLParseError
16 from ndg.xacml.parsers.etree import QName, getElementChildren
17 from ndg.xacml.parsers.etree.reader import ETreeAbstractReader
18 from ndg.xacml.parsers.etree.factory import ReaderFactory
19
20
22 '''ElementTree based XACML generic Match parser for subject, resource,
23 action and environment match types
24
25 @cvar ATTRIBUTE_DESIGNATOR_TYPE: type for attribute designator sub-elements:
26 derived class should set to relevant type e.g. for SubjectMatch,
27 SubjectAttributeDesignator
28 @type ATTRIBUTE_DESIGNATOR_TYPE: NoneType
29 '''
30 ATTRIBUTE_DESIGNATOR_TYPE = None
31
33 """Virtual method
34
35 @raise NotImplementedError: ATTRIBUTE_DESIGNATOR_TYPE must be set in a
36 derived class
37 """
38 if self.__class__.ATTRIBUTE_DESIGNATOR_TYPE is None:
39 raise NotImplementedError('Extend this class setting the '
40 '"ATTRIBUTE_DESIGNATOR_TYPE" class '
41 'variable')
42
43 super(MatchReaderBase, self).__init__()
44
46 """Parse *Match object (where * = Subject, Resource, Environment or
47 Action
48
49 @param obj: input object to parse
50 @type obj: ElementTree Element, or stream object
51 @return: new XACML match instance
52 @rtype: ndg.xacml.core.matchreader.MatchReaderBase derived type
53 @raise XMLParseError: error reading element
54 """
55 elem = super(MatchReaderBase, self)._parse(obj)
56
57 xacmlType = self.__class__.TYPE
58 match = xacmlType()
59
60 localName = QName.getLocalPart(elem.tag)
61 if localName != xacmlType.ELEMENT_LOCAL_NAME:
62 raise XMLParseError("No \"%s\" element found" %
63 xacmlType.ELEMENT_LOCAL_NAME)
64
65
66 attributeValues = []
67 for attributeName in (xacmlType.MATCH_ID_ATTRIB_NAME, ):
68 attributeValue = elem.attrib.get(attributeName)
69 if attributeValue is None:
70 raise XMLParseError('No "%s" attribute found in "%s" '
71 'element' % (attributeName,
72 xacmlType.ELEMENT_LOCAL_NAME))
73
74 attributeValues.append(attributeValue)
75
76 match.matchId, = attributeValues
77
78
79 attributeDesignatorType = self.__class__.ATTRIBUTE_DESIGNATOR_TYPE
80 attributeDesignatorReaderType = ReaderFactory.getReader(
81 attributeDesignatorType)
82
83
84 for childElem in getElementChildren(elem):
85 localName = QName.getLocalPart(childElem.tag)
86
87 if localName == xacmlType.ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME:
88 AttributeValueReader = ReaderFactory.getReader(AttributeValue)
89 match.attributeValue = AttributeValueReader.parse(childElem,
90 common)
91
92 elif localName == attributeDesignatorType.ELEMENT_LOCAL_NAME:
93 if match.attributeSelector is not None:
94 raise XMLParseError("XACML %r child element may only be "
95 "either a %r or %r element NOT both" %
96 (xacmlType.ELEMENT_LOCAL_NAME,
97 attributeDesignatorType.ELEMENT_LOCAL_NAME,
98 AttributeSelector.ELEMENT_LOCAL_NAME))
99
100 match.attributeDesignator = attributeDesignatorReaderType.parse(
101 childElem, common)
102
103 elif localName == AttributeSelector.ELEMENT_LOCAL_NAME:
104 if match.attributeDesignator is not None:
105 raise XMLParseError("XACML %r child element may only be "
106 "either a %r or %r element NOT both" %
107 (xacmlType.ELEMENT_LOCAL_NAME,
108 attributeDesignatorType.ELEMENT_LOCAL_NAME,
109 AttributeSelector.ELEMENT_LOCAL_NAME))
110
111 AttributeSelectorReader = ReaderFactory.getReader(
112 AttributeSelector)
113
114 match.attributeSelector = AttributeSelectorReader.parse(
115 childElem, common)
116 else:
117 raise XMLParseError("XACML %r child element name %r not "
118 "recognised" %
119 (xacmlType.MATCH_TYPE.ELEMENT_LOCAL_NAME,
120 localName))
121
122 return match
123