source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/match.py @ 6806

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/core/match.py@6806
Revision 6806, 6.8 KB checked in by pjkersha, 10 years ago (diff)

Moving matching and rule evaluation code out of the PDP class and into the relevant classes they pertain to e.g. target matching moved to Target class match method and so on.

Line 
1"""NDG Security Match type definition
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "25/02/10"
7__copyright__ = "(C) 2010 Science and Technology Facilities Council"
8__contact__ = "Philip.Kershaw@stfc.ac.uk"
9__license__ = "BSD - see LICENSE file in top-level directory"
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = "$Id: $"
12from ndg.xacml.core import XacmlCoreBase
13from ndg.xacml.core.attributedesignator import AttributeDesignator
14from ndg.xacml.core.attributeselector import AttributeSelector
15from ndg.xacml.core.attributevalue import AttributeValue
16
17
18class MatchBase(XacmlCoreBase):
19    ELEMENT_LOCAL_NAME = None
20    MATCH_ID_ATTRIB_NAME = 'MatchId'
21    ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME = 'AttributeValue'
22
23    __slots__ = (
24        '__attributeValue', 
25        '__attributeDesignator', 
26        '__attributeSelector',
27        '__matchId'
28    )
29   
30    def __init__(self):
31        self.__attributeValue = None
32         
33        # Either/or in schema
34        self.__attributeDesignator = None
35        self.__attributeSelector = None
36       
37        self.__matchId = None
38
39
40    @property
41    def attributeDesignator(self):
42        return self.__attributeDesignator
43   
44    @attributeDesignator.setter
45    def attributeDesignator(self, value):
46        """Set match attribute designator.  Match may have an
47        attributeDesignator or an attributeSelector setting a designator DELETES
48        any attributeSelector previously set
49        """
50        if not isinstance(value, AttributeDesignator):
51            raise TypeError('Expecting %r type for "attributeDesignator" '
52                            'attribute; got %r' % 
53                            (AttributeDesignator, type(value)))
54           
55        self.__attributeDesignator = value
56        self.__attributeSelector = None
57 
58    @property
59    def attributeSelector(self):
60        return self.__attributeSelector
61   
62    @attributeSelector.setter
63    def attributeSelector(self, value):
64        """Set match attribute selector.  Match may have an
65        attributeDesignator or an attributeSelector setting a selector DELETES
66        any attributeDesignator previously set
67        """
68        if not isinstance(value, AttributeSelector):
69            raise TypeError('Expecting %r type for "matchId" '
70                            'attribute; got %r' % 
71                            (AttributeSelector, type(value)))
72           
73        self.__attributeSelector = value
74        self.__attributeDesignator = None
75                       
76    def _getMatchId(self):
77        return self.__matchId
78
79    def _setMatchId(self, value):
80        if not isinstance(value, basestring):
81            raise TypeError('Expecting string type for "matchId" '
82                            'attribute; got %r' % type(value))
83           
84        self.__matchId = value
85
86    matchId = property(_getMatchId, _setMatchId, None, "Match Id")
87   
88    def evaluate(self):
89        """Evaluate the match object against the relevant element in the request
90        context
91        """
92        # Get the match function from the Match ID
93#        matchFunctionClass = self.__functionMap.get(self.matchId)
94#        if matchFunctionClass is NotImplemented:
95#            raise UnsupportedStdFunctionError('No match function class '
96#                                              'implemented for MatchId="%s"'
97#                                              % self.matchId)
98#        elif matchFunctionClass is None:
99#            raise UnsupportedFunctionError('Match function namespace %r is '
100#                                           'not recognised' %
101#                                           self.matchId)
102#           
103#        matchAttributeValue = self.attributeValue.value
104       
105        # Create a match function based on the presence or absence of an
106        # AttributeDesignator or AttributeSelector
107        if self.attributeDesignator is not None:
108#            _attributeMatch = self.attributeDesignatorMatchFuncFactory(
109#                                            matchFunctionClass(),
110#                                            self.attributeValue,
111#                                            self.attributeDesignator)
112           
113        elif self.attributeSelector is not None:
114            # Nb. This will require that the request provide a reference to
115            # it's XML representation and an abstraction of the XML parser
116            # for executing XPath searches into that representation
117            raise UnsupportedElementError('This PDP implementation does '
118                                          'not support <AttributeSelector> '
119                                          'elements')
120        else:
121            _attributeMatch = lambda requestChildAttribute: (
122                matchFunc.evaluate(matchAttributeValue, 
123                                requestChildAttribute.attributeValue.value)
124            )
125   
126        # Iterate through each attribute in the request in turn matching it
127        # against the target using the generated _attributeMatch function
128        #
129        # Any Match element NOT matching will result in an overall status of
130        # no match.
131        #
132        # Continue iterating through the whole list even if a False status
133        # is found.  The other attributes need to be checked in case an
134        # error occurs.  In this case the top-level PDP exception handling
135        # block will catch it and set an overall decision of INDETERMINATE
136        attrMatchStatusValues = [False]*len(requestChild.attributes)
137       
138        for attribute, attrMatchStatus in zip(requestChild.attributes, 
139                                              attrMatchStatusValues):
140            attrMatchStatus = _attributeMatch(attribute)
141            if attrMatchStatus == True:
142                if log.getEffectiveLevel() <= logging.DEBUG:
143                    log.debug('Request attribute %r set to %r matches '
144                              'target',
145                              attribute.attributeId,
146                              [a.value for a in attribute.attributeValues])
147                   
148        matchStatus = all(attrMatchStatusValues)
149       
150        return matchStatus
151   
152   
153class SubjectMatch(MatchBase):
154    "Subject Match Type"
155    ELEMENT_LOCAL_NAME = 'SubjectMatch'
156    ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'SubjectAttributeDesignator'   
157   
158   
159class ResourceMatch(MatchBase):
160    "Resource Match"
161    ELEMENT_LOCAL_NAME = 'ResourceMatch'
162    ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'ResourceAttributeDesignator'
163   
164   
165class ActionMatch(MatchBase):
166    "Action match"
167    ELEMENT_LOCAL_NAME = 'ActionMatch'
168    ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'ActionAttributeDesignator'   
169   
170   
171class EnvironmentMatch(MatchBase):
172    "Environment Match"
173    ELEMENT_LOCAL_NAME = 'EnvironmentMatch'
174    ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'EnvironmentAttributeDesignator'
Note: See TracBrowser for help on using the repository browser.