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

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

Refactored functions package to enable dynamic creation of function classes for all the XACML primitive types for any given function e.g. equal module implements EqualBase? and dynamically creates the <type>-equal classes for all the types: string, AnyURI, Boolean etc.

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