source: TI12-security/trunk/NDG_XACML/ndg/xacml/utils/__init__.py @ 7064

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

Incomplete - task 2: XACML-Security Integration

  • added and and function and placeholders fro xpath-node-* functions
  • Property svn:keywords set to Id
Line 
1"""Utilities package for NDG XACML
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "02/04/09"
7__copyright__ = ""
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11
12# Interpret a string as a boolean
13str2Bool = lambda str: str.lower() in ("yes", "true", "t", "1")
14
15class UniqList(list):
16    """Extended version of list type to enable a list with unique items.
17    If an item is added that is already present then it is silently omitted
18    from the list
19    """
20    def extend(self, iter):
21        return super(UniqList, self).extend([i for i in iter if i not in self])
22       
23    def __iadd__(self, iter):
24        return super(UniqList, self).__iadd__([i for i in iter 
25                                               if i not in self])
26         
27    def append(self, item):
28        for i in self:
29            if i == item:
30                return None
31           
32        return super(UniqList, self).append(item)
33
34
35class TypedList(list):
36    """Extend list type to enabled only items of a given type.  Supports
37    any type where the array type in the Standard Library is restricted to
38    only limited set of primitive types
39    """
40   
41    def __init__(self, elementType, *arg, **kw):
42        """
43        @type elementType: type/tuple
44        @param elementType: object type or types which the list is allowed to
45        contain.  If more than one type, pass as a tuple
46        """
47        self.__elementType = elementType
48        super(TypedList, self).__init__(*arg, **kw)
49
50    def __repr__(self):
51        return "%r type: %s" % (self.__elementType, 
52                                super(TypedList, self).__repr__())
53       
54    def _getElementType(self):
55        return self.__elementType
56   
57    elementType = property(fget=_getElementType, 
58                           doc="The allowed type or types for list elements")
59     
60    def extend(self, iter):
61        for i in iter:
62            if not isinstance(i, self.__elementType):
63                raise TypeError("List items must be of type %s" % 
64                                (self.__elementType,))
65               
66        return super(TypedList, self).extend(iter)
67       
68    def __iadd__(self, iter):
69        for i in iter:
70            if not isinstance(i, self.__elementType):
71                raise TypeError("List items must be of type %s" % 
72                                (self.__elementType,))
73                   
74        return super(TypedList, self).__iadd__(iter)
75         
76    def append(self, item):
77        if not isinstance(item, self.__elementType):
78                raise TypeError("List items must be of type %s" % 
79                                (self.__elementType,))
80   
81        return super(TypedList, self).append(item)
82
83
84class RestrictedKeyNamesDict(dict):
85    """Utility class for holding a constrained list of key names
86    """
87   
88    def __init__(self, *arg, **kw):
89        """Alter standard dict() initialisation to fix key names set at
90        initialisation
91        """
92        super(RestrictedKeyNamesDict, self).__init__(*arg, **kw)
93        self.__keyNames = self.keys() 
94         
95    def __setitem__(self, key, val):
96        if key not in self.__keyNames:
97            raise KeyError('Key name %r not recognised.  Valid key names '
98                           'are: %r' % (key, self.__keyNames))
99           
100        dict.__setitem__(self, key, val)
101
102    def update(self, d, **kw):       
103        for dictArg in (d, kw):
104            for k in dictArg:
105                if k not in self.__keyNames:
106                    raise KeyError('Key name "%s" not recognised.  Valid '
107                                   'key names are: %s' % 
108                                   self.__keyNames)
109       
110        dict.update(self, d, **kw)
111       
112
113_isIterable = lambda obj: getattr(obj, '__iter__', False)
114
115 
116class VettedDict(dict):
117    """Enforce custom checking on keys and items before addition to the
118    dictionary"""
119   
120    def __init__(self, *args):
121        """Initialise setting the allowed type or types for keys and items
122       
123        @param args: two arguments: the first is a callable which filters for
124        permissable keys in this dict, the second sets the type or list of
125        types permissable for items in this dict
126        @type args: tuple
127        """
128        super(VettedDict, self).__init__()
129       
130        if len(args) != 2:
131            raise TypeError('__init__() takes 2 arguments, KeyFilter and '
132                            'valueFilter (%d given)' % len(args))
133       
134        # Validation of inputs
135        for arg, argName in zip(args, ('KeyFilter', 'valueFilter')):
136            if not callable(arg):
137                raise TypeError('Expecting callable for %r input; got %r' % 
138                                (argName, type(arg)))
139
140        self.__KeyFilter, self.__valueFilter = args
141       
142    def _verifyKeyValPair(self, key, val):
143        """Check given key value pair and return False if they should be
144        filtered out.  Filter functions may also raise an exception if they
145        wish to abort completely
146        """
147        if not self.__KeyFilter(key):
148            return False
149       
150        elif not self.__valueFilter(val):
151            return False
152       
153        else:
154            return True
155                 
156    def __setitem__(self, key, val):
157        """Override base class implementation to enforce type checking"""       
158        if self._verifyKeyValPair(key, val):
159            dict.__setitem__(self, key, val)
160
161    def update(self, d, **kw): 
162        """Override base class implementation to enforce type checking"""       
163        for dictArg in (d, kw):
164            for key, val in dictArg.items():
165                if not self._verifyKeyValPair(key, val):
166                    del dictArg[key]
167       
168        dict.update(self, d, **kw)       
169   
Note: See TracBrowser for help on using the repository browser.