Package ndg :: Package xacml :: Package core :: Module match
[hide private]

Source Code for Module ndg.xacml.core.match

  1  """NDG Security Match type definition 
  2   
  3  NERC DataGrid 
  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: match.py 7955 2011-12-21 18:29:45Z rwilkinson $" 
 12  import logging 
 13  log = logging.getLogger(__name__) 
 14   
 15  from ndg.xacml.core import XacmlCoreBase 
 16  from ndg.xacml.core.attributevalue import AttributeValue 
 17  from ndg.xacml.core.attributedesignator import AttributeDesignator 
 18  from ndg.xacml.core.attributeselector import AttributeSelector 
 19  from ndg.xacml.core.functions import (FunctionMap, functionMap, 
 20                                        UnsupportedStdFunctionError, 
 21                                        UnsupportedFunctionError) 
 22  from ndg.xacml.core.context.exceptions import XacmlContextError 
23 24 25 -class MatchBase(XacmlCoreBase):
26 """Base class for representation of SubjectMatch, ResourceMatch, 27 ActionMatch and EnvironmentMatch Target elements 28 29 @cvar ELEMENT_LOCAL_NAME: XML Local Name of this element 30 @type ELEMENT_LOCAL_NAME: string 31 32 @cvar MATCH_ID_ATTRIB_NAME: XML attribute name for match ID 33 @type MATCH_ID_ATTRIB_NAME: string 34 35 @cvar ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME: XML Local Name of attribute value 36 child element 37 @type ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME: string 38 39 @ivar __attributeValue: attribute value associated with this match 40 @type __attributeValue: ndg.xacml.core.attributevalue.AttributeValue 41 @ivar __attributeDesignator: attribute designator - only a designator or 42 selector may be set for a given instance not both 43 @type __attributeDesignator: ndg.xacml.core.attributedesignator.AttributeDesignator 44 @ivar __attributeSelector: attribute selector - only a designator or 45 selector may be set for a given instance not both 46 @type __attributeSelector: ndg.xacml.core.attributeselector.AttributeSelector 47 @ivar __matchId: match identifier 48 @type __matchId: NoneType / basestring 49 @ivar __function: function to be applied 50 @type __function: ndg.xacml.core.functions.AbstractFunction derived type 51 @ivar __functionMap: function mapping object to map URNs to function class 52 implementations 53 @type __functionMap: ndg.xacml.core.functions.FunctionMap 54 @ivar __loadFunctionFromId: boolean determines whether or not to load 55 function classes for given function URN in functionId set property method 56 @type __loadFunctionFromId: bool 57 """ 58 ELEMENT_LOCAL_NAME = None 59 MATCH_ID_ATTRIB_NAME = 'MatchId' 60 ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME = 'AttributeValue' 61 62 __slots__ = ( 63 '__attributeValue', 64 '__attributeDesignator', 65 '__attributeSelector', 66 '__matchId', 67 '__function', 68 '__functionMap', 69 '__loadFunctionFromId', 70 ) 71
72 - def __init__(self):
73 """Initial attributes corresponding to the equivalent XACML schema type 74 and also create a function map to map functions from MatchIds 75 """ 76 self.__attributeValue = None 77 78 # Either/or in schema 79 self.__attributeDesignator = None 80 self.__attributeSelector = None 81 82 self.__matchId = None 83 84 self.__function = None 85 self.__functionMap = functionMap 86 self.__loadFunctionFromId = True
87 88 @property
89 - def attributeValue(self):
90 """Match attribute value 91 92 @return: attribute value 93 @rtype: ndg.xacml.core.attributevalue.Attribute""" 94 return self.__attributeValue
95 96 @attributeValue.setter
97 - def attributeValue(self, value):
98 """Set match attribute value. 99 @param value: attribute value 100 @type value: ndg.xacml.core.attributevalue.AttributeValue 101 @raise TypeError: incorrect type set 102 """ 103 if not isinstance(value, AttributeValue): 104 raise TypeError('Expecting %r type for "matchId" ' 105 'attribute; got %r' % 106 (AttributeValue, type(value))) 107 108 self.__attributeValue = value
109 110 @property
111 - def attributeDesignator(self):
112 """@return: attribute designator - only a designator or 113 selector may be set for a given instance not both 114 @rtype: ndg.xacml.core.attributedesignator.AttributeDesignator 115 """ 116 return self.__attributeDesignator
117 118 @attributeDesignator.setter
119 - def attributeDesignator(self, value):
120 """Set match attribute designator. Match may have an 121 attributeDesignator or an attributeSelector setting a designator DELETES 122 any attributeSelector previously set 123 124 @param value: attribute selector - only a designator or 125 selector may be set for a given instance not both 126 @type value: ndg.xacml.core.attributeselector.AttributeSelector 127 @raise TypeError: incorrect type for input value 128 """ 129 if not isinstance(value, AttributeDesignator): 130 raise TypeError('Expecting %r type for "attributeDesignator" ' 131 'attribute; got %r' % 132 (AttributeDesignator, type(value))) 133 134 self.__attributeDesignator = value 135 self.__attributeSelector = None
136 137 @property
138 - def attributeSelector(self):
139 ''' 140 @return: attribute selector 141 @rtype: ndg.xacml.core.attributeselector.AttributeSelector 142 ''' 143 return self.__attributeSelector
144 145 @attributeSelector.setter
146 - def attributeSelector(self, value):
147 """Set match attribute selector. Match may have an 148 attributeDesignator or an attributeSelector setting a selector DELETES 149 any attributeDesignator previously set 150 151 @param value: attribute selector 152 @type value: ndg.xacml.core.attributeselector.AttributeSelector 153 """ 154 if not isinstance(value, AttributeSelector): 155 raise TypeError('Expecting %r type for "matchId" ' 156 'attribute; got %r' % 157 (AttributeSelector, type(value))) 158 159 self.__attributeSelector = value 160 self.__attributeDesignator = None
161
162 - def _getMatchId(self):
163 """Match identifier for match function 164 @return: match identifier 165 @rtype: NoneType / basestring 166 """ 167 return self.__matchId
168
169 - def _setMatchId(self, value):
170 """Match identifier for match function 171 @param value: match identifier 172 @type value: basestring 173 @raise TypeError: if incorrect input type 174 """ 175 if not isinstance(value, basestring): 176 raise TypeError('Expecting string type for "matchId" ' 177 'attribute; got %r' % type(value)) 178 179 self.__matchId = value 180 181 # Also retrieve function for this match ID if a map has been set 182 if self.__loadFunctionFromId: 183 self.setFunctionFromMap(self.__functionMap)
184 185 matchId = property(_getMatchId, _setMatchId, None, 186 "Match identifier for match function") 187 188 @property
189 - def loadFunctionFromId(self):
190 """Set to False to stop the functionId property set method automatically 191 trying to load the corresponding function for the given functionId 192 193 @return: boolean determines whether or not to load 194 function classes for given function URN in functionId set property 195 method 196 @rtype: bool 197 """ 198 return self.__loadFunctionFromId
199 200 @loadFunctionFromId.setter
201 - def loadFunctionFromId(self, value):
202 """ 203 @param value: boolean determines whether or not to load 204 function classes for given function URN in functionId set property 205 method 206 @type value: bool 207 """ 208 if not isinstance(value, bool): 209 raise TypeError('Expecting %r type for "loadFunctionFromId" ' 210 'attribute; got %r' % (bool, type(value))) 211 212 self.__loadFunctionFromId = value
213
214 - def setFunctionFromMap(self, functionMap):
215 """Set the function from a function map - a dictionary of function ID to 216 function mappings. The function is looked up based on the "functionId" 217 attribute. This method is automatically called when the functionId set 218 property method is invoked. To switch off this behaviour set 219 220 loadFunctionFromId = False 221 222 @param functionMap: mapping of function URNs to function classes 223 @type functionMap: dict like object 224 @raise UnsupportedStdFunctionError: policy references a function type 225 which is in the XACML spec. but is not supported by this implementation 226 @raise UnsupportedFunctionError: policy references a function type which 227 is not supported by this implementation 228 """ 229 if self.matchId is None: 230 raise AttributeError('"functionId" attribute must be set in order ' 231 'to retrieve the required function') 232 233 # Get function class for this <Apply> statement 234 functionClass = functionMap.get(self.matchId) 235 if functionClass is NotImplemented: 236 raise UnsupportedStdFunctionError('No match function class ' 237 'implemented for MatchId="%s"' % 238 self.matchId) 239 elif functionClass is None: 240 raise UnsupportedFunctionError('<Apply> function namespace %r is ' 241 'not recognised' % 242 self.matchId) 243 244 self.__function = functionClass()
245 246 @property
247 - def functionMap(self):
248 """functionMap object for PDP to retrieve functions from given XACML 249 function URNs 250 @return: function mapping object to map URNs to function 251 class implementations 252 @rtype: ndg.xacml.core.functions.FunctionMap 253 """ 254 return self.__functionMap
255 256 @functionMap.setter
257 - def functionMap(self, value):
258 '''functionMap object for PDP to retrieve functions from given XACML 259 function URNs 260 261 @param value: function mapping object to map URNs to function class 262 implementations 263 @type value: ndg.xacml.core.functions.FunctionMap 264 @raise TypeError: raise if input value is incorrect type 265 ''' 266 if not isinstance(value, FunctionMap): 267 raise TypeError('Expecting %r derived type for "functionMap" ' 268 'input; got %r instead' % (FunctionMap, 269 type(value))) 270 self.__functionMap = value
271 272 @property
273 - def function(self):
274 """Function for this <Apply> instance 275 @return: function to be applied 276 @rtype: ndg.xacml.core.functions.AbstractFunction derived type 277 """ 278 return self.__function
279
280 - def evaluate(self, context):
281 """Evaluate the match object against the relevant element in the request 282 context 283 284 @param context: the request context 285 @type context: ndg.xacml.core.context.request.Request 286 @return: match status 287 @rtype: bool 288 """ 289 290 # Create a match function based on the presence or absence of an 291 # AttributeDesignator or AttributeSelector 292 if self.attributeDesignator is not None: 293 requestAttributeValues = self.attributeDesignator.evaluate(context) 294 295 elif self.attributeSelector is not None: 296 # Nb. Evaluation is not currently supported. This will require that 297 # the request provide a reference to it's XML representation and an 298 # abstraction of the XML parser for executing XPath searches into 299 # that representation 300 requestAttributeValues = self.attributeSelector.evaluate(context) 301 else: 302 raise XacmlContextError('No attribute designator or selector set ' 303 'for Target Match element %r with MatchId ' 304 '= %r and attributeValue = %r' % 305 (self.__class__.ELEMENT_LOCAL_NAME, 306 self.matchId, 307 self.attributeValue)) 308 309 # Iterate through each attribute in the request in turn matching it 310 # against the target using the generated _attributeMatch function. 311 # The target match attribute must match any of the request attributes 312 # for an overall True match status. 313 # 314 # Continue iterating through the whole list even if a True status 315 # is found. The other attributes need to be checked in case an 316 # error occurs. In this case the top-level PDP exception handling 317 # block will catch it and set an overall decision of INDETERMINATE. 318 attrMatchStatusValues = [False]*len(requestAttributeValues) 319 matchFunction = self.function 320 matchAttributeValue = self.attributeValue 321 322 for i, requestAttributeValue in enumerate(requestAttributeValues): 323 324 attrMatchStatusValues[i] = matchFunction.evaluate( 325 matchAttributeValue, 326 requestAttributeValue) 327 if attrMatchStatusValues[i] == True: 328 if log.getEffectiveLevel() <= logging.DEBUG: 329 log.debug('Target attribute value %r matches request ' 330 'attribute value %r matches using match ' 331 'function Id %r', 332 matchAttributeValue, 333 requestAttributeValue, 334 self.matchId) 335 336 # Return true if a match was found. 337 matchStatus = any(attrMatchStatusValues) 338 339 return matchStatus
340
341 342 -class SubjectMatch(MatchBase):
343 "Subject Match Type" 344 ELEMENT_LOCAL_NAME = 'SubjectMatch' 345 ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'SubjectAttributeDesignator'
346
347 348 -class ResourceMatch(MatchBase):
349 "Resource Match" 350 ELEMENT_LOCAL_NAME = 'ResourceMatch' 351 ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'ResourceAttributeDesignator'
352
353 354 -class ActionMatch(MatchBase):
355 "Action match" 356 ELEMENT_LOCAL_NAME = 'ActionMatch' 357 ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'ActionAttributeDesignator'
358
359 360 -class EnvironmentMatch(MatchBase):
361 "Environment Match" 362 ELEMENT_LOCAL_NAME = 'EnvironmentMatch' 363 ATTRIBUTE_DESIGNATOR_ELEMENT_LOCAL_NAME = 'EnvironmentAttributeDesignator'
364