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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/core/rule.py@6806
Revision 6806, 6.4 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 Rule 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.utils import TypedList
13from ndg.xacml.core import XacmlCoreBase
14from ndg.xacml.core.target import Target
15from ndg.xacml.core.condition import Condition
16
17
18class Effect(object):
19    """Rule Effect"""
20    DENY_STR = 'Deny'
21    PERMIT_STR = 'Permit'
22    TYPES = (DENY_STR, PERMIT_STR)
23    __slots__ = ('__value',)
24   
25    def __init__(self, effect=DENY_STR):
26        self.__value = None
27        self.value = effect
28
29    def __getstate__(self):
30        '''Enable pickling'''
31        _dict = {}
32        for attrName in Effect.__slots__:
33            # Ugly hack to allow for derived classes setting private member
34            # variables
35            if attrName.startswith('__'):
36                attrName = "_Effect" + attrName
37               
38            _dict[attrName] = getattr(self, attrName)
39           
40        return _dict
41 
42    def __setstate__(self, attrDict):
43        '''Enable pickling'''
44        for attrName, val in attrDict.items():
45            setattr(self, attrName, val)
46           
47    def _setValue(self, value):
48        if isinstance(value, Effect):
49            # Cast to string
50            value = str(value)
51           
52        elif not isinstance(value, basestring):
53            raise TypeError('Expecting string or Effect instance for '
54                            '"value" attribute; got %r instead' % type(value))
55           
56        if value not in self.__class__.TYPES:
57            raise AttributeError('Permissable effect types are %r; got '
58                                 '%r instead' % (Effect.TYPES, value))
59        self.__value = value
60       
61    def _getValue(self):
62        return self.__value
63   
64    value = property(fget=_getValue, fset=_setValue, doc="Effect value")
65   
66    def __str__(self):
67        return self.__value
68
69    def __eq__(self, effect):
70        if isinstance(effect, Effect):
71            # Cast to string
72            value = effect.value
73           
74        elif isinstance(effect, basestring):
75            value = effect
76           
77        else:
78            raise TypeError('Expecting string or Effect instance for '
79                            'input effect value; got %r instead' % type(value))
80           
81        if value not in self.__class__.TYPES:
82            raise AttributeError('Permissable effect types are %r; got '
83                                 '%r instead' % (Effect.TYPES, value))
84           
85        return self.__value == value       
86
87
88class PermitEffect(Effect):
89    """Permit authorisation Effect"""
90    __slots__ = ()
91
92    def __init__(self):
93        super(PermitEffect, self).__init__(Effect.PERMIT_STR)
94       
95    def _setValue(self): 
96        raise AttributeError("can't set attribute")
97
98
99class DenyEffect(Effect):
100    """Deny authorisation Effect"""
101    __slots__ = ()
102   
103    def __init__(self):
104        super(DenyEffect, self).__init__(Effect.DENY_STR)
105       
106    def _setValue(self, value): 
107        raise AttributeError("can't set attribute")
108
109# Add instances of each for convenience
110Effect.PERMIT = PermitEffect()
111Effect.DENY = DenyEffect()
112
113
114class Rule(XacmlCoreBase):
115    """XACML Policy Rule"""
116    ELEMENT_LOCAL_NAME = 'Rule'
117    RULE_ID_ATTRIB_NAME = 'RuleId'
118    EFFECT_ATTRIB_NAME = 'Effect'
119   
120    DESCRIPTION_LOCAL_NAME = 'Description'
121   
122    __slots__ = (
123        '__target', 
124        '__condition', 
125        '__description', 
126        '__id', 
127        '__effect'
128    )
129   
130    def __init__(self):
131        self.__id = None
132        self.__effect = None
133        self.__target = None
134        self.__condition = None
135       
136    @property
137    def target(self):
138        "Rule target"
139        return self.__target
140   
141    @target.setter
142    def target(self, value):
143        if not isinstance(value, Target):
144            raise TypeError('Expecting %r type for "id" '
145                            'attribute; got %r' % (Target, type(value))) 
146        self.__target = value
147           
148    @property
149    def condition(self):
150        "rule condition"
151        return self.__condition
152   
153    @condition.setter
154    def condition(self, value):
155        if not isinstance(value, Condition):
156            raise TypeError('Expecting %r type for "id" '
157                            'attribute; got %r' % (Condition, type(value))) 
158           
159        self.__condition = value
160             
161    def _get_id(self):
162        return self.__id
163
164    def _set_id(self, value):
165        if not isinstance(value, basestring):
166            raise TypeError('Expecting %r type for "id" '
167                            'attribute; got %r' % (basestring, type(value)))
168         
169        self.__id = value   
170
171    id = property(_get_id, _set_id, None, "Rule identifier attribute") 
172     
173    def _get_effect(self):
174        return self.__effect
175
176    def _set_effect(self, value):
177        if not isinstance(value, Effect):
178            raise TypeError('Expecting %r type for "effect" '
179                            'attribute; got %r' % (Effect, type(value)))
180           
181        self.__effect = value   
182
183    effect = property(_get_effect, _set_effect, None, 
184                      "Rule effect attribute") 
185
186    def _getDescription(self):
187        return self.__description
188
189    def _setDescription(self, value):
190        if not isinstance(value, basestring):
191            raise TypeError('Expecting string type for "description" '
192                            'attribute; got %r' % type(value))
193        self.__description = value
194
195    description = property(_getDescription, _setDescription, 
196                           doc="Rule Description text")
197   
198    def evaluate(self, context):
199        """Evaluate a rule
200        @param context: the request context
201        @type context: ndg.xacml.core.request.Request
202        @return: result of the evaluation - the decision for this rule
203        @rtype:
204        """
205        log.debug('Evaluating rule %r ...', rule.id)
206       
207        if not self.matchTarget(self.target, request):
208            log.debug('No match to request context for target in rule '
209                      '%r', self.id)
210            #ruleStatusValues[i] = True
211            continue   
212       
213        # Apply the condition
214        ruleStatusValues[i] = self.condition.evaluate()
215
Note: See TracBrowser for help on using the repository browser.