source: TI12-security/trunk/ndg_xacml/ndg/xacml/core/apply.py @ 7351

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

Incomplete - task 2: XACML-Security Integration

  • important fix to ndg.xacml.core.rule.Rule.evaluate: return NotApplicable? where Target matches but Condition does not match
  • optimised ndg.xacml.core.functions.v1.at_least_one_member_of.AtLeastOneMemberOfBase? to use set and '&' operator for this function.
  • fix to ndg.xacml.core.functions.FunctionMap?.loadFunction to catch function namespace not recognised.
  • Property svn:keywords set to Id
Line 
1"""NDG Security Condition type definition
2
3NERC DataGrid
4"""
5__author__ = "P J Kershaw"
6__date__ = "19/03/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.utils import TypedList
13from ndg.xacml.core.expression import Expression
14from ndg.xacml.core.functions import (FunctionMap, UnsupportedStdFunctionError,
15                                      UnsupportedFunctionError)
16
17
18class Apply(Expression):
19    """XACML Apply type
20   
21    @cvar ELEMENT_LOCAL_NAME: XML element local name
22    @type ELEMENT_LOCAL_NAME: string
23    @cvar FUNCTION_ID_ATTRIB_NAME: function ID XML attribute name
24    @type FUNCTION_ID_ATTRIB_NAME: string
25
26    @ivar __functionId: URN corresponding to function to be applied
27    @type __functionId: basestring/NoneType
28    @ivar __function: function to be applied
29    @type __function: ndg.xacml.core.functions.AbstractFunction derived type
30    @ivar __functionMap: function mapping object to map URNs to function class
31    implementations
32    @type __functionMap: ndg.xacml.core.functions.FunctionMap
33    @ivar __loadFunctionFromId: boolean determines whether or not to load
34    function classes for given function URN in functionId set property method
35    @type __loadFunctionFromId: bool
36    @ivar __expressions: list of expressions contained in the Apply statement
37    @type __expressions: ndg.xacml.utils.TypedList
38    """
39    ELEMENT_LOCAL_NAME = 'Apply'
40    FUNCTION_ID_ATTRIB_NAME = 'FunctionId'
41   
42    __slots__ = (
43        '__functionId', 
44        '__function', 
45        '__functionMap',
46        '__loadFunctionFromId',
47        '__expressions'
48    )
49   
50    def __init__(self):
51        """Initialise attributes"""
52        super(Apply, self).__init__()
53        self.__functionId = None
54        self.__function = None
55        self.__functionMap = FunctionMap()
56        self.__loadFunctionFromId = True
57        self.__expressions = TypedList(Expression)
58     
59    @property
60    def loadFunctionFromId(self):
61        """Set to False to stop the functionId property set method automatically
62        trying to load the corresponding function for the given functionId
63       
64        @return: flag setting
65        @rtype: bool""" 
66        return self.__loadFunctionFromId
67   
68    @loadFunctionFromId.setter
69    def loadFunctionFromId(self, value):
70        """Set to False to stop the functionId property set method automatically
71        trying to load the corresponding function for the given functionId
72       
73        @param value: flag setting
74        @type value: bool
75        @raise TypeError: incorrect input type
76        """ 
77        if not isinstance(value, bool):
78            raise TypeError('Expecting %r type for "loadFunctionFromId" '
79                            'attribute; got %r' % (bool, type(value)))
80           
81        self.__loadFunctionFromId = value
82       
83    def _get_functionId(self):
84        """Get function ID
85        @return: function ID for this Apply statement
86        @rtype: basestring/NoneType
87        """
88        return self.__functionId
89
90    def _set_functionId(self, value):
91        """Set function ID
92        @param value: function URN
93        @type value: basestring
94        @raise TypeError: incorrect input type
95        """ 
96        if not isinstance(value, basestring):
97            raise TypeError('Expecting %r type for "functionId" '
98                            'attribute; got %r' % (basestring, type(value)))
99           
100        self.__functionId = value
101       
102        # Also retrieve function for this function ID if a map has been set
103        if self.__loadFunctionFromId:
104            self.setFunctionFromMap(self.__functionMap)   
105
106    functionId = property(_get_functionId, _set_functionId, None, 
107                          "Apply type Function ID") 
108       
109    def setFunctionFromMap(self, functionMap):
110        """Set the function from a function map - a dictionary of function ID to
111        function mappings.  The function is looked up based on the "functionId"
112        attribute.  This method is automatically called when the functionId set
113        property method is invoked.  To switch off this behaviour set
114       
115        loadFunctionFromId = False
116   
117        @param functionMap: function mapping object to map URNs to function
118        class implementations
119        @type functionMap: ndg.xacml.core.functions.FunctionMap
120       
121        @raise UnsupportedStdFunctionError: policy references a function type
122        which is in the XACML spec. but is not supported by this implementation
123        @raise UnsupportedFunctionError: policy references a function type which
124        is not supported by this implementation
125        """
126        if self.functionId is None:
127            raise AttributeError('"functionId" attribute must be set in order '
128                                 'to retrieve the required function')
129           
130        # Get function class for this <Apply> statement         
131        functionClass = functionMap.get(self.functionId)
132        if functionClass is NotImplemented:
133            raise UnsupportedStdFunctionError('No match function class '
134                                              'implemented for MatchId="%s"' % 
135                                              self.functionId)
136        elif functionClass is None:
137            raise UnsupportedFunctionError('<Apply> function namespace %r is '
138                                           'not recognised' % 
139                                           self.functionId) 
140           
141        self.__function = functionClass()
142   
143    @property
144    def functionMap(self):
145        """functionMap object for PDP to retrieve functions from given XACML
146        function URNs
147        @return: function mapping object
148        @rtype: ndg.xacml.core.functions.FunctionMap
149        """
150        return self.__functionMap
151   
152    @functionMap.setter
153    def functionMap(self, value):
154        '''functionMap object for PDP to retrieve functions from given XACML
155        function URNs
156        @param value: function mapping object to map URNs to function
157        class implementations
158        @type value: ndg.xacml.core.functions.FunctionMap
159        @raise TypeError: incorrect type for input value
160        '''
161        if not isinstance(value, FunctionMap):
162            raise TypeError('Expecting %r derived type for "functionMap" '
163                            'input; got %r instead' % (FunctionMap, 
164                                                       type(value)))
165        self.__functionMap = value
166         
167    @property 
168    def function(self):
169        """Get Function for this <Apply> instance
170        @return: function to be applied
171        @rtype: ndg.xacml.core.functions.AbstractFunction derived type
172        """
173        return self.__function
174       
175    @property
176    def expressions(self):
177        """List of expression sub-elements
178        @return: list of expressions contained in the Apply statement
179        @rtype: ndg.xacml.utils.TypedList
180        """
181        return self.__expressions
182   
183    def evaluate(self, context):
184        """Evaluate a given <Apply> statement in a rule condition
185       
186        @param context: the request context
187        @type context: ndg.xacml.core.context.request.Request
188        @return: attribute value(s) resulting from execution of this expression
189        in a condition
190        @rtype: AttributeValue/NoneType
191        """ 
192       
193        # Marshall inputs
194        funcInputs = [None]*len(self.expressions)
195
196        for i, expression in enumerate(self.expressions):
197            funcInputs[i] = expression.evaluate(context)
198           
199        # Execute function on the retrieved inputs
200        result = self.function.evaluate(*tuple(funcInputs))
201       
202        # Pass the result back to the parent <Apply> element
203        return result
204         
Note: See TracBrowser for help on using the repository browser.