source: TI12-security/trunk/ndg_xacml/ndg/xacml/core/attributedesignator.py @ 7109

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/ndg_xacml/ndg/xacml/core/attributedesignator.py@7109
Revision 7109, 14.4 KB checked in by pjkersha, 10 years ago (diff)

Incomplete - task 2: XACML-Security Integration

  • updating epydoc ready for release.
  • Property svn:keywords set to Id
Line 
1"""NDG XACML AttributeDesignator type
2
3NERC DataGrid
4"""
5__author__ = "P J Kershaw"
6__date__ = "16/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.attributevalue import (AttributeValue, 
15                                           AttributeValueClassFactory)
16from ndg.xacml.core.context.request import Request
17from ndg.xacml.core.context.handler import CtxHandlerInterface
18from ndg.xacml.core.context.exceptions import MissingAttributeError
19
20
21class AttributeDesignator(Expression):
22    '''Base class for XACML Attribute Designator types
23   
24    @cvar ATTRIBUTE_ID_ATTRIB_NAME: attribute ID XML attribute name
25    @type ATTRIBUTE_ID_ATTRIB_NAME: string
26    @cvar ISSUER_ATTRIB_NAME: issuer XML attribute name
27    @type ISSUER_ATTRIB_NAME: string
28    @cvar MUST_BE_PRESENT_ATTRIB_NAME: must be present XML attribute name
29    @type MUST_BE_PRESENT_ATTRIB_NAME: string
30   
31    @ivar __attributeId: attribute ID for this designator
32    @type __attributeId: basestring / NoneType
33    @ivar __issuer: issuer if the designator
34    @type __issuer: basestring / NoneType
35    @ivar __mustBePresent: XML must be present flag
36    @type __mustBePresent: bool
37    @ivar __attributeValueFactory: When evaluating matches, use an attribute
38    value class factory to create attribute values for match bag of the correct
39    DataType to respect type based rule functions
40    @type __attributeValueFactory: ndg.xacml.core.attributevalue.AttributeValueClassFactory
41    '''
42    ATTRIBUTE_ID_ATTRIB_NAME = 'AttributeId'
43    ISSUER_ATTRIB_NAME = 'Issuer'
44    MUST_BE_PRESENT_ATTRIB_NAME = 'MustBePresent'
45   
46    __slots__ = (
47        '__attributeId', 
48        '__issuer', 
49        '__mustBePresent',
50        '__attributeValueFactory'
51    )
52   
53    def __init__(self):
54        """Initialise attributes"""
55        super(AttributeDesignator, self).__init__()
56        self.__attributeId = None
57        self.__issuer = None
58        self.__mustBePresent = False
59       
60        # When evaluating matches, use an attribute value class factory to
61        # create attribute values for match bag of the correct DataType to
62        # respect type based rule functions
63        self.__attributeValueFactory = AttributeValueClassFactory()
64
65    @property
66    def attributeId(self):
67        """Get Attribute Id
68        @return: attribute ID
69        @rtype: basestring / NoneType
70        """
71        return self.__attributeId
72
73    @attributeId.setter
74    def attributeId(self, value):
75        """Set Attribute Id
76        @param value: attribute ID
77        @type value: basestring
78        @raise TypeError: incorrect input type
79        """
80        if not isinstance(value, basestring):
81            raise TypeError('Expecting %r type for "attributeId" '
82                            'attribute; got %r' % (basestring, type(value)))
83           
84        self.__attributeId = value 
85       
86    @property
87    def issuer(self):
88        """Get Issuer
89        @return: issuer
90        @rtype: basestring / NoneType
91        """
92        return self.__issuer
93
94    @issuer.setter
95    def issuer(self, value):
96        """Set Issuer
97        @param value: issuer
98        @type value: basestring
99        @raise TypeError: incorrect input type
100        """
101        if not isinstance(value, basestring):
102            raise TypeError('Expecting %r type for "issuer" '
103                            'attribute; got %r' % (basestring, type(value)))
104           
105        self.__issuer = value   
106
107    @property
108    def mustBePresent(self):
109        """Get Must Be Present flag
110        @return: must be present flag
111        @rtype: bool
112        """
113        return self.__mustBePresent
114
115    @mustBePresent.setter
116    def mustBePresent(self, value):
117        """Set Must Be Present flag
118        @param value: must be present flag
119        @type value: bool
120        @raise TypeError: incorrect input type
121        """
122        if not isinstance(value, bool):
123            raise TypeError('Expecting %r type for "mustBePresent" '
124                            'attribute; got %r' % (bool, type(value)))
125           
126        self.__mustBePresent = value   
127             
128    @property
129    def attributeValueFactory(self):
130        """Get Attribute Value factory function
131       
132        @return: attribute value factory instance
133        @rtype: ndg.xacml.core.attributevalue.AttributeValueClassFactory
134        """
135        return self.__attributeValueFactory
136                           
137       
138class SubjectAttributeDesignator(AttributeDesignator):
139    """XACML Subject Attribute Designator type
140    @cvar ELEMENT_LOCAL_NAME: XML local name for this element
141    @type ELEMENT_LOCAL_NAME: string
142    """
143    ELEMENT_LOCAL_NAME = 'SubjectAttributeDesignator'
144    __slots__ = ()
145   
146    def evaluate(self, context):
147        """Evaluate the result of the SubjectAttributeDesignator in a condition
148       
149        @param context: the request context
150        @type context: ndg.xacml.core.context.request.Request
151        @return: attribute value(s) resulting from execution of this expression
152        in a condition
153        @rtype: AttributeValue/NoneType 
154        """ 
155        if not isinstance(context, Request):
156            raise TypeError('Expecting %r type for context input; got %r' %
157                            (Request, type(context)))
158       
159        dataType = self.dataType
160        attributeValueBag = TypedList(self.attributeValueFactory(dataType))
161        attributeId = self.attributeId
162        issuer = self.issuer
163       
164        if issuer is not None:
165            _issuerMatch = lambda _issuer: issuer == _issuer
166        else:
167            _issuerMatch = lambda _issuer: True
168       
169        _attributeMatch = lambda attr: (attr.attributeId == attributeId and 
170                                        attr.dataType == dataType and
171                                        _issuerMatch(attr.issuer))
172                                       
173        for subject in context.subjects: 
174            for attr in subject.attributes:
175                if _attributeMatch(attr):
176                    attributeValueBag.extend([i for i in attr.attributeValues
177                                              if i.dataType == dataType])
178                   
179            if context.ctxHandler is not None and len(attributeValueBag) == 0:
180                # No match was found - try querying the Policy Information
181                # Point via the Context Handler to see if values for the
182                # attribute specified in this designator can be retrieved
183                # externally. If retrieved, it's added to the bag.  The input
184                # subject may be updated too so that the values are cached for
185                # subsequent requests
186                attributeValues = context.ctxHandler.pipQuery(subject, self)
187                attributeValueBag.extend(attributeValues)
188                   
189        if len(attributeValueBag) == 0 and self.mustBePresent:
190            raise MissingAttributeError('"MustBePresent" is set for %r but no '
191                                        'match for attributeId=%r, dataType=%r '
192                                        'and issuer=%r' % 
193                                        (self.__class__.__name__,
194                                         self.attributeId,
195                                         self.dataType,
196                                         self.issuer)) 
197                       
198        return attributeValueBag
199       
200       
201class ResourceAttributeDesignator(AttributeDesignator):
202    """XACML Resource Attribute Designator type
203    @cvar ELEMENT_LOCAL_NAME: XML local name for this element
204    @type ELEMENT_LOCAL_NAME: string
205    """
206    ELEMENT_LOCAL_NAME = 'ResourceAttributeDesignator'
207    __slots__ = ()
208   
209    def evaluate(self, context):
210        """Evaluate the result of the ResourceAttributeDesignator in a condition
211       
212        @param context: the request context
213        @type context: ndg.xacml.core.context.request.Request
214        @return: attribute value(s) resulting from execution of this expression
215        in a condition
216        @rtype: AttributeValue/NoneType 
217        """ 
218        if not isinstance(context, Request):
219            raise TypeError('Expecting %r type for context input; got %r' %
220                            (Request, type(context)))
221       
222        dataType = self.dataType
223        attributeValueBag = TypedList(self.attributeValueFactory(dataType))
224        attributeId = self.attributeId
225        issuer = self.issuer
226       
227        if issuer is not None:
228            _issuerMatch = lambda _issuer: issuer == _issuer
229        else:
230            _issuerMatch = lambda _issuer: True
231       
232        _attributeMatch = lambda attr: (attr.attributeId == attributeId and 
233                                        attr.dataType == dataType and
234                                        _issuerMatch(attr.issuer))
235                   
236        for resource in context.resources:
237            for attr in resource.attributes:
238                if _attributeMatch(attr):
239                    attributeValueBag.extend([i for i in attr.attributeValues
240                                              if i.dataType == dataType])
241                   
242        if len(attributeValueBag) == 0 and self.mustBePresent:
243            raise MissingAttributeError('"MustBePresent" is set for %r but no '
244                                        'match for attributeId=%r, dataType=%r '
245                                        'and issuer=%r' % 
246                                        (self.__class__.__name__,
247                                         self.attributeId,
248                                         self.dataType,
249                                         self.issuer)) 
250                       
251        return attributeValueBag
252   
253       
254class ActionAttributeDesignator(AttributeDesignator):
255    """XACML Action Attribute Designator type
256    @cvar ELEMENT_LOCAL_NAME: XML local name for this element
257    @type ELEMENT_LOCAL_NAME: string
258    """
259    ELEMENT_LOCAL_NAME = 'ActionAttributeDesignator'
260    __slots__ = ()
261   
262    def evaluate(self, context):
263        """Evaluate the result of the ActionAttributeDesignator in a condition
264       
265        @param context: the request context
266        @type context: ndg.xacml.core.context.request.Request
267        @return: attribute value(s) resulting from execution of this expression
268        in a condition
269        @rtype: AttributeValue/NoneType 
270        """ 
271        if not isinstance(context, Request):
272            raise TypeError('Expecting %r type for context input; got %r' %
273                            (Request, type(context)))
274       
275        dataType = self.dataType
276        attributeValueBag = TypedList(self.attributeValueFactory(dataType))
277        attributeId = self.attributeId
278        issuer = self.issuer
279        action = context.action
280       
281        if issuer is not None:
282            _issuerMatch = lambda _issuer: issuer == _issuer
283        else:
284            _issuerMatch = lambda _issuer: True
285       
286        _attributeMatch = lambda attr: (attr.attributeId == attributeId and 
287                                        attr.dataType == dataType and
288                                        _issuerMatch(attr.issuer))
289                   
290        for attr in action.attributes:
291            if _attributeMatch(attr):
292                attributeValueBag.extend([i for i in attr.attributeValues
293                                          if i.dataType == dataType])
294                   
295        if len(attributeValueBag) == 0 and self.mustBePresent:
296            raise MissingAttributeError('"MustBePresent" is set for %r but no '
297                                        'match for attributeId=%r, dataType=%r '
298                                        'and issuer=%r' % 
299                                        (self.__class__.__name__,
300                                         self.attributeId,
301                                         self.dataType,
302                                         self.issuer)) 
303                       
304        return attributeValueBag   
305   
306   
307class EnvironmentAttributeDesignator(AttributeDesignator):
308    """XACML Environment Attribute Designator type
309    @cvar ELEMENT_LOCAL_NAME: XML local name for this element
310    @type ELEMENT_LOCAL_NAME: string
311    """
312    ELEMENT_LOCAL_NAME = 'EnvironmentAttributeDesignator'
313    __slots__ = ()
314   
315    def evaluate(self, context):
316        """Evaluate the result of the EnvironmentAttributeDesignator in a
317        condition
318       
319        @param context: the request context
320        @type context: ndg.xacml.core.context.request.Request
321        @return: attribute value(s) resulting from execution of this expression
322        in a condition
323        @rtype: AttributeValue/NoneType 
324        """ 
325        if not isinstance(context, Request):
326            raise TypeError('Expecting %r type for context input; got %r' %
327                            (Request, type(context)))
328       
329        dataType = self.dataType
330        attributeValueBag = TypedList(self.attributeValueFactory(dataType))
331        attributeId = self.attributeId
332        issuer = self.issuer
333        environment = context.environment
334       
335        if issuer is not None:
336            _issuerMatch = lambda _issuer: issuer == _issuer
337        else:
338            _issuerMatch = lambda _issuer: True   
339       
340        _attributeMatch = lambda attr: (attr.attributeId == attributeId and 
341                                        attr.dataType == dataType and
342                                        _issuerMatch(attr.issuer))
343                 
344        for attr in environment.attributes:
345            if _attributeMatch(attr):
346                attributeValueBag.extend([i for i in attr.attributeValues
347                                          if i.dataType == dataType])
348                   
349        if len(attributeValueBag) == 0 and self.mustBePresent:
350            raise MissingAttributeError('"MustBePresent" is set for %r but no '
351                                        'match for attributeId=%r, dataType=%r '
352                                        'and issuer=%r' % 
353                                        (self.__class__.__name__,
354                                         self.attributeId,
355                                         self.dataType,
356                                         self.issuer)) 
357                       
358        return attributeValueBag
Note: See TracBrowser for help on using the repository browser.