source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/apply.py @ 6804

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

Working class factories for each function module. Function class evaluate methods need to be refactored to accept *AttributeValue? types

Line 
1"""NDG Security Condition type definition
2
3NERC DataGrid Project
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
15from ndg.xacml.core.exceptions import (UnsupportedStdFunctionError,
16                                       UnsupportedFunctionError)
17
18
19class Apply(Expression):
20    """XACML Apply type"""
21    ELEMENT_LOCAL_NAME = 'Apply'
22    FUNCTION_ID_ATTRIB_NAME = 'FunctionId'
23   
24    __slots__ = (
25        '__functionId', 
26        '__function', 
27        '__functionMap',
28        '__loadFunctionFromId',
29        '__expressions'
30    )
31   
32    def __init__(self):
33        super(Apply, self).__init__()
34        self.__functionId = None
35        self.__function = None
36        self.__functionMap = FunctionMap.withLoadedMap()
37        self.__loadFunctionFromId = True
38        self.__expressions = TypedList(Expression)
39     
40    @property
41    def loadFunctionFromId(self):
42        """Set to False to stop the functionId property set method automatically
43        trying to load the corresponding function for the given functionId""" 
44        return self.__loadFunctionFromId
45   
46    @loadFunctionFromId.setter
47    def loadFunctionFromId(self, value):
48        if not isinstance(value, bool):
49            raise TypeError('Expecting %r type for "loadFunctionFromId" '
50                            'attribute; got %r' % (bool, type(value)))
51           
52        self.__functionId = value
53       
54    def _get_functionId(self):
55        return self.__functionId
56
57    def _set_functionId(self, value):
58        if not isinstance(value, basestring):
59            raise TypeError('Expecting %r type for "functionId" '
60                            'attribute; got %r' % (basestring, type(value)))
61           
62        self.__functionId = value
63       
64        # Also retrieve function for this function ID if a map has been set
65        if self.__loadFunctionFromId:
66            self.setFunctionFromMap(self.__functionMap)   
67
68    functionId = property(_get_functionId, _set_functionId, None, 
69                          "Apply type Function ID") 
70       
71    def setFunctionFromMap(self, functionMap):
72        """Set the function from a function map - a dictionary of function ID to
73        function mappings.  The function is looked up based on the "functionId"
74        attribute.  This method is automatically called when the functionId set
75        property method is invoked.  To switch off this behaviour set
76       
77        loadFunctionFromId = False
78       
79        @raise UnsupportedStdFunctionError: policy references a function type
80        which is in the XACML spec. but is not supported by this implementation
81        @raise UnsupportedFunctionError: policy references a function type which
82        is not supported by this implementation
83        """
84        if self.functionId is None:
85            raise AttributeError('"functionId" attribute must be set in order '
86                                 'to retrieve the required function')
87           
88        # Get function class for this <Apply> statement         
89        functionClass = functionMap.get(self.functionId)
90        if functionClass is NotImplemented:
91            raise UnsupportedStdFunctionError('No match function class '
92                                              'implemented for MatchId="%s"' % 
93                                              self.functionId)
94        elif functionClass is None:
95            raise UnsupportedFunctionError('<Apply> function namespace %r is '
96                                           'not recognised' % 
97                                           self.functionId) 
98           
99        self.__function = functionClass()
100   
101    @property
102    def functionMap(self):
103        """functionMap object for PDP to retrieve functions from given XACML
104        function URNs"""
105        return self.__functionMap
106   
107    @functionMap.setter
108    def functionMap(self, value):
109        '''functionMap object for PDP to retrieve functions from given XACML
110        function URNs'''
111        if not isinstance(value, FunctionMap):
112            raise TypeError('Expecting %r derived type for "functionMap" '
113                            'input; got %r instead' % (FunctionMap, 
114                                                       type(value)))
115        self.__functionMap = value
116         
117    @property 
118    def function(self):
119        "Function for this <Apply> instance"
120        return self.__function
121       
122    @property
123    def expressions(self):
124        """List of expression sub-elements"""
125        return self.__expressions
126   
127    def evaluate(self, context):
128        """Evaluate a given <Apply> statement in a rule condition
129       
130        @param context: the request context
131        @type context: ndg.xacml.core.context.request.Request
132        @return: attribute value(s) resulting from execution of this expression
133        in a condition
134        @rtype: AttributeValue/NoneType
135        """ 
136       
137        # Marshall inputs
138        funcInputs = ['']*len(self.expressions)
139
140        for i, expression in enumerate(self.expressions):
141            funcInputs[i] = expression.evaluate(context)
142           
143        # Execute function on the retrieved inputs
144        result = self.function.evaluate(*tuple(funcInputs))
145       
146        # Pass the result back to the parent <Apply> element
147        return result
148         
Note: See TracBrowser for help on using the repository browser.