source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/result.py @ 7064

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/result.py@7064
Revision 7064, 12.2 KB checked in by pjkersha, 10 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"""NDG XACML module for Result type
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "23/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$"
12import logging
13log = logging.getLogger(__name__)
14
15from ndg.xacml.core.context import XacmlContextBase
16from ndg.xacml.core.obligation import Obligation
17
18
19class StatusCode(XacmlContextBase):
20    '''XACML Response Result StatusCode.'''
21   
22    # Local Name of StatusCode.
23    ELEMENT_LOCAL_NAME = "StatusCode"
24
25    IDENTIFIER_PREFIX = XacmlContextBase.XACML_1_0_NS_PREFIX + ':status'
26   
27    OK = IDENTIFIER_PREFIX + ":ok"
28    MISSING_ATTRIBUTE = IDENTIFIER_PREFIX + ":missing-attribute"
29    PROCESSING_ERROR = IDENTIFIER_PREFIX + ":processing-error"
30    SYNTAX_ERROR = IDENTIFIER_PREFIX + ":syntax-error"
31   
32    CODES = (OK, MISSING_ATTRIBUTE, PROCESSING_ERROR, SYNTAX_ERROR)
33   
34    __slots__ = ('__value', '__childStatusCode',)
35   
36    def __init__(self, **kw):
37        super(StatusCode, self).__init__(**kw)
38       
39        # Value attribute URI.
40        self.__value = None
41   
42        # Nested secondary StatusCode child element.
43        self.__childStatusCode = None
44
45    def _getStatusCode(self): 
46        return self.__childStatusCode
47   
48    def _setStatusCode(self, value):
49        if not isinstance(value, StatusCode):
50            raise TypeError('Child "statusCode" must be a %r derived type, '
51                            "got %r" % (StatusCode, type(value)))
52           
53        self.__childStatusCode = value
54
55    value = property(fget=_getStatusCode, 
56                     fset=_setStatusCode, 
57                     doc="Child Status code")
58             
59    def _getValue(self):
60        return self.__value
61       
62    def _setValue(self, value):
63        if not isinstance(value, basestring):
64            raise TypeError("\"value\" must be a basestring derived type, "
65                            "got %r" % value.__class__)
66       
67        if value not in self.__class__.CODES:
68            raise AttributeError('Status code expected values are %r; got %r' %
69                                 (self.__class__.CODES, value))
70               
71        self.__value = value
72
73    value = property(fget=_getValue, fset=_setValue, doc="Status code value")
74   
75
76class Status(XacmlContextBase): 
77    '''XACML Response Result Status'''
78   
79    # Local Name of Status.
80    ELEMENT_LOCAL_NAME = "Status"
81
82    __slots__ = ('__statusCode', '__statusMessage', '__statusDetail', )
83   
84    def __init__(self, **kw):
85        super(Status, self).__init__(**kw)
86       
87        # StatusCode element.
88        self.__statusCode = None
89   
90        # StatusMessage element.
91        self.__statusMessage = None
92   
93        # StatusDetail element.
94        self.__statusDetail = None
95   
96    @classmethod
97    def createInitialised(cls, code=StatusCode.OK, message='', detail=''):
98        """Create with an empty StatusCode object set
99        """
100        status = cls()
101        status.statusCode = StatusCode()
102        status.statusCode.value = code
103        status.statusMessage = message
104        status.statusDetail = detail
105       
106        return status
107       
108    def _getStatusCode(self):
109        '''
110        Gets the Code of this Status.
111       
112        @return: Status StatusCode
113        '''
114        return self.__statusCode
115
116    def _setStatusCode(self, value):
117        '''
118        Sets the Code of this Status.
119       
120        @param value: the Code of this Status
121        '''
122        if not isinstance(value, StatusCode):
123            raise TypeError('"statusCode" must be a %r derived type, '
124                            "got %r" % (StatusCode, type(value)))
125           
126        self.__statusCode = value
127       
128    statusCode = property(fget=_getStatusCode,
129                          fset=_setStatusCode,
130                          doc="status code object")
131   
132    def _getStatusMessage(self):
133        '''
134        Gets the Message of this Status.
135       
136        @return: Status StatusMessage
137        '''
138        return self.__statusMessage
139
140    def _setStatusMessage(self, value):
141        '''
142        Sets the Message of this Status.
143       
144        @param value: the Message of this Status
145        '''
146        if not isinstance(value, basestring):
147            raise TypeError('"statusMessage" must be a %r derived type, '
148                            "got %r" % (basestring, type(value)))
149           
150        self.__statusMessage = value
151       
152    statusMessage = property(fget=_getStatusMessage,
153                             fset=_setStatusMessage,
154                             doc="status message")
155
156    def _getStatusDetail(self):
157        '''
158        Gets the Detail of this Status.
159       
160        @return: Status StatusDetail
161        '''
162        return self.__statusDetail
163   
164    def _setStatusDetail(self, value):
165        '''
166        Sets the Detail of this Status.
167       
168        @param value: the Detail of this Status
169        '''
170        self.__statusDetail = value
171       
172    statusDetail = property(fget=_getStatusDetail,
173                            fset=_setStatusDetail,
174                            doc="status message")
175           
176
177class Decision(object):
178    """Define decision types for Response Result"""
179   
180    # "Permit" decision type
181    PERMIT_STR = "Permit"
182   
183    # "Deny" decision type
184    DENY_STR = "Deny"
185   
186    # "Indeterminate" decision type
187    INDETERMINATE_STR = "Indeterminate"
188   
189    NOT_APPLICABLE_STR = "NotApplicable"
190       
191    TYPES = (PERMIT_STR, DENY_STR, INDETERMINATE_STR, NOT_APPLICABLE_STR)
192   
193    __slots__ = ('__value',)
194   
195    def __init__(self, decision=INDETERMINATE_STR):
196        self.__value = None
197        self.value = decision
198
199    def __getstate__(self):
200        '''Enable pickling'''
201        _dict = {}
202        for attrName in Decision.__slots__:
203            # Ugly hack to allow for derived classes setting private member
204            # variables
205            if attrName.startswith('__'):
206                attrName = "_Decision" + attrName
207               
208            _dict[attrName] = getattr(self, attrName)
209           
210        return _dict
211 
212    def __setstate__(self, attrDict):
213        '''Enable pickling'''
214        for attrName, val in attrDict.items():
215            setattr(self, attrName, val)
216           
217    def _setValue(self, value):
218        if isinstance(value, Decision):
219            # Cast to string
220            value = str(value)
221           
222        elif not isinstance(value, basestring):
223            raise TypeError('Expecting string or Decision instance for '
224                            '"value" attribute; got %r instead' % type(value))
225           
226        if value not in self.__class__.TYPES:
227            raise AttributeError('Permissable decision types are %r; got '
228                                 '%r instead' % (Decision.TYPES, value))
229        self.__value = value
230       
231    def _getValue(self):
232        return self.__value
233   
234    value = property(fget=_getValue, fset=_setValue, doc="Decision value")
235   
236    def __str__(self):
237        return self.__value
238
239    def __repr__(self):
240        return "%s = %r" % (super(Decision, self).__repr__(), self.__value)
241   
242    def __eq__(self, decision):
243        if isinstance(decision, Decision):
244            # Cast to string
245            value = decision.value
246           
247        elif isinstance(decision, basestring):
248            value = decision
249           
250        else:
251            raise TypeError('Expecting string or Decision instance for '
252                            'input decision value; got %r instead' % type(value))
253           
254        if value not in self.__class__.TYPES:
255            raise AttributeError('Permissable decision types are %r; got '
256                                 '%r instead' % (Decision.TYPES, value))
257           
258        return self.__value == value       
259
260
261class PermitDecision(Decision):
262    """Permit authorisation Decision"""
263    __slots__ = ()
264
265    def __init__(self):
266        super(PermitDecision, self).__init__(Decision.PERMIT_STR)
267       
268    def _setValue(self): 
269        raise AttributeError("can't set attribute")
270
271
272class DenyDecision(Decision):
273    """Deny authorisation Decision"""
274    __slots__ = ()
275   
276    def __init__(self):
277        super(DenyDecision, self).__init__(Decision.DENY_STR)
278       
279    def _setValue(self, value): 
280        raise AttributeError("can't set attribute")
281
282
283class IndeterminateDecision(Decision):
284    """Indeterminate authorisation Decision"""
285    __slots__ = ()
286   
287    def __init__(self):
288        super(IndeterminateDecision, self).__init__(Decision.INDETERMINATE_STR)
289       
290    def _setValue(self, value): 
291        raise AttributeError("can't set attribute")
292
293
294class NotApplicableDecision(Decision):
295    """NotApplicable authorisation Decision"""
296    __slots__ = ()
297   
298    def __init__(self):
299        super(NotApplicableDecision, self).__init__(Decision.NOT_APPLICABLE_STR)
300       
301    def _setValue(self, value): 
302        raise AttributeError("can't set attribute")
303   
304   
305# Add instances of each for convenience
306Decision.PERMIT = PermitDecision()
307Decision.DENY = DenyDecision()
308Decision.INDETERMINATE = IndeterminateDecision()
309Decision.NOT_APPLICABLE = NotApplicableDecision()
310
311
312class Result(XacmlContextBase):
313    """XACML Result type - element in a Response"""
314    __slots__ = ('__resourceId', '__decision', '__status', '__obligations')
315   
316    ELEMENT_LOCAL_NAME  = 'Result'
317    OBLIGATIONS_ELEMENT_LOCAL_NAME = 'Obligations'
318    REOSURCE_ID_ATTRIB_NAME = 'ResourceId'
319   
320    def __init__(self):
321        super(Result, self).__init__()
322        self.__decision = None
323        self.__status = None
324        self.__resourceId = None
325        self.__obligations = None
326       
327    @classmethod
328    def createInitialised(cls, 
329                          decision=Decision.NOT_APPLICABLE,
330                          resourceId='', 
331                          obligations=None,
332                          **kw):
333        """Create a result object populated with all it's child elements
334        rather than set to None as is the default from __init__
335        @return: new result object with all its child attributes created
336        @rtype: ndg.xacml.core.context.result.Result
337        """
338        result = cls()
339        result.decision = Decision()
340        result.decision.value = decision
341        result.status = Status.createInitialised(**kw)
342       
343        if obligations is not None:
344            result.obligations = obligations
345           
346        return result
347       
348    @property
349    def resourceId(self):
350        """Result resource Id"""
351        return self.__resourceId
352
353    @resourceId.setter
354    def resourceId(self, value):
355        """Result resource Id"""
356        if not isinstance(value, basestring):
357            raise TypeError('Expecting %r type for "resourceId" '
358                            'result; got %r' % (basestring, type(value)))
359           
360        self.__resourceId = value
361                       
362    @property
363    def decision(self):
364        """Result decision"""
365        return self.__decision
366   
367    @decision.setter
368    def decision(self, value):
369        """Request decision"""
370        if not isinstance(value, Decision):
371            raise TypeError('Expecting %r type for result "decision" '
372                            'attribute; got %r' % (Decision, type(value)))
373        self.__decision = value
374       
375    @property
376    def status(self):
377        """Result status"""
378        return self.__status
379   
380    @status.setter
381    def status(self, value):
382        """Result status"""
383        if not isinstance(value, Status):
384            raise TypeError('Expecting %r type for result "status" '
385                            'attribute; got %r' % (Status, type(value)))
386           
387        self.__status = value
388                                   
389    @property
390    def obligations(self):
391        """Result obligation"""
392        return self.__obligations
393   
394    @obligations.setter
395    def obligations(self, value):
396        """Result obligation"""
397        if not isinstance(value, Obligation):
398            raise TypeError('Expecting %r type for result "obligations" '
399                            'attribute; got %r' % (Obligation, type(value)))
400           
401        self.__obligations = value
Note: See TracBrowser for help on using the repository browser.