source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/functions/__init__.py @ 6802

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

Fixed AttributeValueReader? to handler attribute value derived types correctly.

Line 
1"""NDG XACML package for match functions
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "26/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 abc import ABCMeta, abstractmethod
13
14from ndg.xacml.utils import VettedDict
15from ndg.xacml.utils.factory import callModuleObject
16
17from datetime import datetime, timedelta
18
19
20class AbstractFunction(object):
21    """Base class for all XACML matching functions"""
22   
23    __metaclass__ = ABCMeta
24    FUNCTION_NS = None
25    V1_0_FUNCTION_NS = "urn:oasis:names:tc:xacml:1.0:function:"
26    V2_0_FUNCTION_NS = "urn:oasis:names:tc:xacml:2.0:function:"
27   
28    def __init__(self):
29        if self.__class__.FUNCTION_NS is None:
30            raise TypeError('"FUNCTION_NS" class variable must be defined in '
31                            'derived classes')
32#    @classmethod
33#    def __subclasshook__(cls, C):
34#        if cls is AbstractFunction:
35#            if
36#            return True
37#        else:
38#            return NotImplemented
39           
40    @abstractmethod
41    def evaluate(self, *inputs):
42        """Evaluate the function from the given input arguments and context
43        @param inputs: input arguments need to evaluate the function
44        @type inputs: tuple
45        @return: True for match, False otherwise
46        @rtype: bool
47        """
48       
49class XacmlFunctionNames(object):
50    """XACML standard match function names"""
51    FUNCTION_NAMES = (
52        'urn:oasis:names:tc:xacml:1.0:function:string-equal',
53        'urn:oasis:names:tc:xacml:1.0:function:boolean-equal',
54        'urn:oasis:names:tc:xacml:1.0:function:integer-equal',
55        'urn:oasis:names:tc:xacml:1.0:function:double-equal',
56        'urn:oasis:names:tc:xacml:1.0:function:date-equal',
57        'urn:oasis:names:tc:xacml:1.0:function:time-equal',
58        'urn:oasis:names:tc:xacml:1.0:function:dateTime-equal',
59        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-equal',
60        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-equal',
61        'urn:oasis:names:tc:xacml:1.0:function:anyURI-equal',
62        'urn:oasis:names:tc:xacml:1.0:function:x500Name-equal',
63        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal',
64        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal',
65        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal',
66        'urn:oasis:names:tc:xacml:1.0:function:integer-add',
67        'urn:oasis:names:tc:xacml:1.0:function:double-add',
68        'urn:oasis:names:tc:xacml:1.0:function:integer-subtract',
69        'urn:oasis:names:tc:xacml:1.0:function:double-subtract',
70        'urn:oasis:names:tc:xacml:1.0:function:integer-multiply',
71        'urn:oasis:names:tc:xacml:1.0:function:double-multiply',
72        'urn:oasis:names:tc:xacml:1.0:function:integer-divide',
73        'urn:oasis:names:tc:xacml:1.0:function:double-divide',
74        'urn:oasis:names:tc:xacml:1.0:function:integer-mod',
75        'urn:oasis:names:tc:xacml:1.0:function:integer-abs',
76        'urn:oasis:names:tc:xacml:1.0:function:double-abs',
77        'urn:oasis:names:tc:xacml:1.0:function:round',
78        'urn:oasis:names:tc:xacml:1.0:function:floor',
79        'urn:oasis:names:tc:xacml:1.0:function:string-normalize-space',
80        'urn:oasis:names:tc:xacml:1.0:function:string-normalize-to-lower-case',
81        'urn:oasis:names:tc:xacml:1.0:function:double-to-integer',
82        'urn:oasis:names:tc:xacml:1.0:function:integer-to-double',
83        'urn:oasis:names:tc:xacml:1.0:function:or',
84        'urn:oasis:names:tc:xacml:1.0:function:and',
85        'urn:oasis:names:tc:xacml:1.0:function:n-of',
86        'urn:oasis:names:tc:xacml:1.0:function:not',
87        'urn:oasis:names:tc:xacml:1.0:function:integer-greater-than',
88        'urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal',
89        'urn:oasis:names:tc:xacml:1.0:function:integer-less-than',
90        'urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal',
91        'urn:oasis:names:tc:xacml:1.0:function:double-greater-than',
92        'urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal',
93        'urn:oasis:names:tc:xacml:1.0:function:double-less-than',
94        'urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal',
95        'urn:oasis:names:tc:xacml:1.0:function:dateTime-add-dayTimeDuration',
96        'urn:oasis:names:tc:xacml:1.0:function:dateTime-add-yearMonthDuration',
97        'urn:oasis:names:tc:xacml:1.0:function:dateTime-subtract-dayTimeDuration',
98        'urn:oasis:names:tc:xacml:1.0:function:dateTime-subtract-yearMonthDuration', 
99        'urn:oasis:names:tc:xacml:1.0:function:date-add-yearMonthDuration',
100        'urn:oasis:names:tc:xacml:1.0:function:date-subtract-yearMonthDuration',
101        'urn:oasis:names:tc:xacml:1.0:function:string-greater-than',
102        'urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal',
103        'urn:oasis:names:tc:xacml:1.0:function:string-less-than',
104        'urn:oasis:names:tc:xacml:1.0:function:string-less-than-or-equal',
105        'urn:oasis:names:tc:xacml:1.0:function:time-greater-than',
106        'urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal',
107        'urn:oasis:names:tc:xacml:1.0:function:time-less-than',
108        'urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal',
109        'urn:oasis:names:tc:xacml:2.0:function:time-in-range',
110        'urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than',
111        'urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal',
112        'urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than',
113        'urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal',
114        'urn:oasis:names:tc:xacml:1.0:function:date-greater-than',
115        'urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal',
116        'urn:oasis:names:tc:xacml:1.0:function:date-less-than',
117        'urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal',
118        'urn:oasis:names:tc:xacml:1.0:function:string-one-and-only',
119        'urn:oasis:names:tc:xacml:1.0:function:string-bag-size',
120        'urn:oasis:names:tc:xacml:1.0:function:string-is-in',
121        'urn:oasis:names:tc:xacml:1.0:function:string-bag',
122        'urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only',
123        'urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size',
124        'urn:oasis:names:tc:xacml:1.0:function:boolean-is-in',
125        'urn:oasis:names:tc:xacml:1.0:function:boolean-bag',
126        'urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only',
127        'urn:oasis:names:tc:xacml:1.0:function:integer-bag-size',
128        'urn:oasis:names:tc:xacml:1.0:function:integer-is-in',
129        'urn:oasis:names:tc:xacml:1.0:function:integer-bag',
130        'urn:oasis:names:tc:xacml:1.0:function:double-one-and-only',
131        'urn:oasis:names:tc:xacml:1.0:function:double-bag-size',
132        'urn:oasis:names:tc:xacml:1.0:function:double-is-in',
133        'urn:oasis:names:tc:xacml:1.0:function:double-bag',
134        'urn:oasis:names:tc:xacml:1.0:function:time-one-and-only',
135        'urn:oasis:names:tc:xacml:1.0:function:time-bag-size',
136        'urn:oasis:names:tc:xacml:1.0:function:time-is-in',
137        'urn:oasis:names:tc:xacml:1.0:function:time-bag',
138        'urn:oasis:names:tc:xacml:1.0:function:date-one-and-only',
139        'urn:oasis:names:tc:xacml:1.0:function:date-bag-size',
140        'urn:oasis:names:tc:xacml:1.0:function:date-is-in',
141        'urn:oasis:names:tc:xacml:1.0:function:date-bag',
142        'urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only',
143        'urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size',
144        'urn:oasis:names:tc:xacml:1.0:function:dateTime-is-in',
145        'urn:oasis:names:tc:xacml:1.0:function:dateTime-bag',
146        'urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only',
147        'urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size',
148        'urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in',
149        'urn:oasis:names:tc:xacml:1.0:function:anyURI-bag',
150        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only',
151        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size',
152        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-is-in',
153        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag',
154        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only',
155        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size',
156        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-is-in',
157        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag',
158        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-one-and-only',
159        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-bag-size',
160        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-is-in',
161        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-bag',
162        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-one-and-only',
163        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-bag-size',
164        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-is-in',
165        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-bag',
166        'urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only',
167        'urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size',
168        'urn:oasis:names:tc:xacml:1.0:function:x500Name-is-in',
169        'urn:oasis:names:tc:xacml:1.0:function:x500Name-bag',
170        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only',
171        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size',
172        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-is-in',
173        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag',
174        'urn:oasis:names:tc:xacml:2.0:function:string-concatenate',
175        'urn:oasis:names:tc:xacml:2.0:function:uri-string-concatenate',
176        'urn:oasis:names:tc:xacml:1.0:function:any-of',
177        'urn:oasis:names:tc:xacml:1.0:function:all-of',
178        'urn:oasis:names:tc:xacml:1.0:function:any-of-any',
179        'urn:oasis:names:tc:xacml:1.0:function:all-of-any',
180        'urn:oasis:names:tc:xacml:1.0:function:any-of-all',
181        'urn:oasis:names:tc:xacml:1.0:function:all-of-all',
182        'urn:oasis:names:tc:xacml:1.0:function:map',
183        'urn:oasis:names:tc:xacml:1.0:function:x500Name-match',
184        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match',
185        'urn:oasis:names:tc:xacml:1.0:function:string-regexp-match',
186        'urn:oasis:names:tc:xacml:2.0:function:anyURI-regexp-match',
187        'urn:oasis:names:tc:xacml:2.0:function:ipAddress-regexp-match',
188        'urn:oasis:names:tc:xacml:2.0:function:dnsName-regexp-match',
189        'urn:oasis:names:tc:xacml:2.0:function:rfc822Name-regexp-match',
190        'urn:oasis:names:tc:xacml:2.0:function:x500Name-regexp-match',
191        'urn:oasis:names:tc:xacml:1.0:function:xpath-node-count',
192        'urn:oasis:names:tc:xacml:1.0:function:xpath-node-equal',
193        'urn:oasis:names:tc:xacml:1.0:function:xpath-node-match',
194        'urn:oasis:names:tc:xacml:1.0:function:string-intersection',
195        'urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of',
196        'urn:oasis:names:tc:xacml:1.0:function:string-union',
197        'urn:oasis:names:tc:xacml:1.0:function:string-subset',
198        'urn:oasis:names:tc:xacml:1.0:function:string-set-equals',
199        'urn:oasis:names:tc:xacml:1.0:function:boolean-intersection',
200        'urn:oasis:names:tc:xacml:1.0:function:boolean-at-least-one-member-of',
201        'urn:oasis:names:tc:xacml:1.0:function:boolean-union',
202        'urn:oasis:names:tc:xacml:1.0:function:boolean-subset',
203        'urn:oasis:names:tc:xacml:1.0:function:boolean-set-equals',
204        'urn:oasis:names:tc:xacml:1.0:function:integer-intersection',
205        'urn:oasis:names:tc:xacml:1.0:function:integer-at-least-one-member-of',
206        'urn:oasis:names:tc:xacml:1.0:function:integer-union',
207        'urn:oasis:names:tc:xacml:1.0:function:integer-subset',
208        'urn:oasis:names:tc:xacml:1.0:function:integer-set-equals',
209        'urn:oasis:names:tc:xacml:1.0:function:double-intersection',
210        'urn:oasis:names:tc:xacml:1.0:function:double-at-least-one-member-of',
211        'urn:oasis:names:tc:xacml:1.0:function:double-union',
212        'urn:oasis:names:tc:xacml:1.0:function:double-subset',
213        'urn:oasis:names:tc:xacml:1.0:function:double-set-equals',
214        'urn:oasis:names:tc:xacml:1.0:function:time-intersection',
215        'urn:oasis:names:tc:xacml:1.0:function:time-at-least-one-member-of',
216        'urn:oasis:names:tc:xacml:1.0:function:time-union',
217        'urn:oasis:names:tc:xacml:1.0:function:time-subset',
218        'urn:oasis:names:tc:xacml:1.0:function:time-set-equals',
219        'urn:oasis:names:tc:xacml:1.0:function:date-intersection',
220        'urn:oasis:names:tc:xacml:1.0:function:date-at-least-one-member-of',
221        'urn:oasis:names:tc:xacml:1.0:function:date-union',
222        'urn:oasis:names:tc:xacml:1.0:function:date-subset',
223        'urn:oasis:names:tc:xacml:1.0:function:date-set-equals',
224        'urn:oasis:names:tc:xacml:1.0:function:dateTime-intersection',
225        'urn:oasis:names:tc:xacml:1.0:function:dateTime-at-least-one-member-of',
226        'urn:oasis:names:tc:xacml:1.0:function:dateTime-union',
227        'urn:oasis:names:tc:xacml:1.0:function:dateTime-subset',
228        'urn:oasis:names:tc:xacml:1.0:function:dateTime-set-equals',
229        'urn:oasis:names:tc:xacml:1.0:function:anyURI-intersection',
230        'urn:oasis:names:tc:xacml:1.0:function:anyURI-at-least-one-member-of',
231        'urn:oasis:names:tc:xacml:1.0:function:anyURI-union',
232        'urn:oasis:names:tc:xacml:1.0:function:anyURI-subset',
233        'urn:oasis:names:tc:xacml:1.0:function:anyURI-set-equals',
234        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-intersection',
235        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-at-least-one-member-of',
236        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-union',
237        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-subset',
238        'urn:oasis:names:tc:xacml:1.0:function:hexBinary-set-equals',
239        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-intersection',
240        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-at-least-one-member-of',
241        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-union',
242        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-subset',
243        'urn:oasis:names:tc:xacml:1.0:function:base64Binary-set-equals',
244        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-intersection',
245        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-at-least-one-member-of',
246        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-union',
247        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-subset',
248        'urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-set-equals',
249        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-intersection',
250        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-at-least-one-member-of',
251        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-union',
252        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-subset',
253        'urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-set-equals',
254        'urn:oasis:names:tc:xacml:1.0:function:x500Name-intersection',
255        'urn:oasis:names:tc:xacml:1.0:function:x500Name-at-least-one-member-of',
256        'urn:oasis:names:tc:xacml:1.0:function:x500Name-union',
257        'urn:oasis:names:tc:xacml:1.0:function:x500Name-subset',
258        'urn:oasis:names:tc:xacml:1.0:function:x500Name-set-equals',
259        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-intersection',
260        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-at-least-one-member-of',
261        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-union',
262        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-subset',
263        'urn:oasis:names:tc:xacml:1.0:function:rfc822Name-set-equals',
264    )
265
266
267class FunctionMapError(Exception):
268    """Generic Error exception class for FunctionMap"""
269   
270   
271class FunctionMapConfigError(FunctionMapError):
272    """Configuration related exception for FunctionMap"""
273       
274       
275class FunctionMap(VettedDict):
276    """Map function IDs to their implementations"""
277    FUNCTION_PKG_PREFIX = 'ndg.xacml.core.functions.'
278   
279    V1_0_PKG_PREFIX = FUNCTION_PKG_PREFIX + 'v1.'
280    V2_0_PKG_PREFIX = FUNCTION_PKG_PREFIX + 'v2.'
281   
282    SUPPORTED_NSS = {
283        AbstractFunction.V1_0_FUNCTION_NS: V1_0_PKG_PREFIX,
284        AbstractFunction.V2_0_FUNCTION_NS: V2_0_PKG_PREFIX
285    }
286   
287    def __init__(self):
288        """Force function entries to derive from AbstractFunction and IDs to
289        be string type
290        """       
291        # Filters are defined as staticmethods but reference via self here to
292        # enable derived class to override them as standard methods without
293        # needing to redefine this __init__ method           
294        super(FunctionMap, self).__init__(self.keyFilter, self.valueFilter)
295       
296    @staticmethod
297    def keyFilter(key):
298        """Enforce string type keys"""
299        if not isinstance(key, basestring):
300            raise TypeError('Expecting %r type for key; got %r' % 
301                            (basestring, type(key))) 
302        return True 
303   
304    @staticmethod
305    def valueFilter(value):
306        """Enforce AbstractFunction derived types for match functions"""
307
308        if not isinstance(value, 
309                          (AbstractFunction, NotImplemented.__class__)):
310            raise TypeError('Expecting %r derived type for value; got %r' % 
311                            (AbstractFunction, type(value))) 
312        return True 
313           
314    def load(self):
315        """Load function map with implementations from the relevant function
316        package"""
317       
318        for functionNs in XacmlFunctionNames.FUNCTION_NAMES:
319            self._loadFunction(functionNs)
320           
321    @classmethod
322    def withLoadedMap(cls):
323        """Return a pre-loaded map"""
324        functionMap = cls()
325        functionMap.load()
326        return functionMap
327           
328    def _loadFunction(self, functionNs):
329        """Get package to retrieve function class from for given namespace
330        """
331        cls = FunctionMap
332        classPath = None
333       
334        if functionNs == "urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of":
335            pass
336
337        for namespacePrefix, pkgNamePrefix in cls.SUPPORTED_NSS.items():
338            if functionNs.startswith(namespacePrefix):
339                # Namespace is recognised - translate into a path to a function
340                # class in the right functions package
341                functionName = functionNs.split(namespacePrefix)[-1]
342                functionNameParts = functionName.split('-')
343               
344                if len(functionNameParts) == 1:
345                    moduleName = functionNameParts[0]
346                else:
347                    moduleName = '_'.join(functionNameParts[1:]).lower()
348                   
349                className = ''.join([n[0].upper() + n[1:] 
350                                     for n in functionNameParts])
351                classPath = pkgNamePrefix + moduleName + '.' + className
352                break
353
354        if classPath is None:
355            raise FunctionMapConfigError('Namespace for function not '
356                                         'recognised: %r' % functionNs) 
357                       
358        # Try instantiating the function class and loading it into the
359        # map
360        try:
361            matchFunctionObj = callModuleObject(classPath)
362            self[functionNs] = matchFunctionObj
363        except ImportError:
364            # No implementation exists - default to Abstract function
365            self[functionNs] = NotImplemented
366           
367
368
369       
Note: See TracBrowser for help on using the repository browser.