1 """NDG XACML module for Result type
2
3 NERC DataGrid
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: result.py 8010 2012-01-30 16:24:06Z rwilkinson $"
12 import logging
13 log = logging.getLogger(__name__)
14
15 from ndg.xacml.core.context import XacmlContextBase
16 from ndg.xacml.core.obligation import Obligation
20 '''XACML Response Result StatusCode.
21
22 @cvar ELEMENT_LOCAL_NAME: XML Local Name of StatusCode element
23 @type ELEMENT_LOCAL_NAME: string
24
25 @cvar IDENTIFIER_PREFIX: namespace prefix for status codes
26 @type IDENTIFIER_PREFIX: string
27
28 @cvar OK: OK response status
29 @type OK: string
30
31 @cvar MISSING_ATTRIBUTE: missing attribute response status
32 @type MISSING_ATTRIBUTE: string
33
34 @cvar PROCESSING_ERROR: response status indicating a processing error
35 @type PROCESSING_ERROR: string
36
37 @cvar SYNTAX_ERROR: response status for a syntax error
38 @type SYNTAX_ERROR: string
39
40 @cvar CODES: list of recognised codes
41 @type CODES: tuple
42
43 @ivar __value: status code value
44 @type __value: basestring
45
46 @ivar __childStatusCode: child status code
47 @type __childStatusCode: ndg.xacml.core.result.StatusCode
48 '''
49
50 ELEMENT_LOCAL_NAME = "StatusCode"
51
52 IDENTIFIER_PREFIX = XacmlContextBase.XACML_1_0_NS_PREFIX + ':status'
53
54 OK = IDENTIFIER_PREFIX + ":ok"
55 MISSING_ATTRIBUTE = IDENTIFIER_PREFIX + ":missing-attribute"
56 PROCESSING_ERROR = IDENTIFIER_PREFIX + ":processing-error"
57 SYNTAX_ERROR = IDENTIFIER_PREFIX + ":syntax-error"
58
59 CODES = (OK, MISSING_ATTRIBUTE, PROCESSING_ERROR, SYNTAX_ERROR)
60
61 __slots__ = ('__value', '__childStatusCode',)
62
71
73 '''@return: child status code
74 @rtype: ndg.xacml.core.result.StatusCode
75 '''
76 return self.__childStatusCode
77
79 '''@param value: child status code
80 @type value: ndg.xacml.core.result.StatusCode
81 '''
82 if not isinstance(value, StatusCode):
83 raise TypeError('Child "statusCode" must be a %r derived type, '
84 "got %r" % (StatusCode, type(value)))
85
86 self.__childStatusCode = value
87
88 value = property(fget=_getStatusCode,
89 fset=_setStatusCode,
90 doc="Child Status code")
91
93 '''@return: status code value
94 @rtype: basestring
95 '''
96 return self.__value
97
99 '''@param value: status code value
100 @type value: basestring
101 '''
102 if not isinstance(value, basestring):
103 raise TypeError("\"value\" must be a basestring derived type, "
104 "got %r" % value.__class__)
105
106 if value not in self.__class__.CODES:
107 raise AttributeError('Status code expected values are %r; got %r' %
108 (self.__class__.CODES, value))
109
110 self.__value = value
111
112 value = property(fget=_getValue, fset=_setValue, doc="Status code value")
113
114
115 -class Status(XacmlContextBase):
116 '''XACML Response Result Status
117
118 @cvar ELEMENT_LOCAL_NAME: XML Local Name of Status element
119 @type ELEMENT_LOCAL_NAME: string
120
121 @ivar __statusCode: Status code element
122 @type __statusCode: None / ndg.xacml.core.context.result.StatusCode
123 @ivar __statusMessage: Status message element
124 @type __statusMessage: None / basestring
125 @ivar __statusDetail: Status detail element
126 @type __statusDetail: None / any type
127 '''
128
129
130 ELEMENT_LOCAL_NAME = "Status"
131
132 __slots__ = ('__statusCode', '__statusMessage', '__statusDetail', )
133
145
146 @classmethod
148 """Create with an empty StatusCode object set
149
150 @param code: Status code - defaults to OK code
151 @type code: basestring
152 @param message: Status Message
153 @type message: basestring
154 @param detail: Status detail
155 @type detail: string / any
156 @return: Status instance
157 @rtype: ndg.xacml.core.context.Status
158 """
159 status = cls()
160 status.statusCode = StatusCode()
161 status.statusCode.value = code
162 status.statusMessage = message
163 status.statusDetail = detail
164
165 return status
166
168 '''
169 Gets the Code of this Status.
170
171 @return: Status StatusCode
172 @rtype: ndg.xacml.core.context.StatusCode
173 '''
174 return self.__statusCode
175
177 '''
178 Sets the Code of this Status.
179
180 @param value: the Code of this Status
181 @type value: ndg.xacml.core.context.StatusCode
182 '''
183 if not isinstance(value, StatusCode):
184 raise TypeError('"statusCode" must be a %r derived type, '
185 "got %r" % (StatusCode, type(value)))
186
187 self.__statusCode = value
188
189 statusCode = property(fget=_getStatusCode,
190 fset=_setStatusCode,
191 doc="status code object")
192
194 '''
195 Gets the Message of this Status.
196
197 @return: Status StatusMessage
198 @rtype: basestring
199 '''
200 return self.__statusMessage
201
203 '''
204 Sets the Message of this Status.
205
206 @param value: the Message of this Status
207 @type value: basestring
208 '''
209 if not isinstance(value, basestring):
210 raise TypeError('"statusMessage" must be a %r derived type, '
211 "got %r" % (basestring, type(value)))
212
213 self.__statusMessage = value
214
215 statusMessage = property(fget=_getStatusMessage,
216 fset=_setStatusMessage,
217 doc="status message")
218
220 '''
221 Gets the Detail of this Status.
222
223 @return: Status detail
224 @rtype: any
225 '''
226 return self.__statusDetail
227
229 '''
230 Sets the Detail of this Status.
231
232 @param value: the Detail of this Status
233 @type value: any type
234 '''
235 self.__statusDetail = value
236
237 statusDetail = property(fget=_getStatusDetail,
238 fset=_setStatusDetail,
239 doc="status message")
240
243 """Define decision types for Response Result
244
245 @cvar ELEMENT_LOCAL_NAME: XML Local Name of StatusCode element
246 @type ELEMENT_LOCAL_NAME: string
247
248 @cvar PERMIT_STR: permit decision string
249 @type PERMIT_STR: string
250
251 @cvar DENY_STR: deny decision string
252 @type DENY_STR: string
253
254 @cvar INDETERMINATE_STR: indeterminate decision string
255 @type INDETERMINATE_STR: string
256
257 @cvar NOT_APPLICABLE_STR: not applicable decision string
258 @type NOT_APPLICABLE_STR: string
259
260 @cvar TYPES: list of valid decision strings
261 @type TYPES: tuple
262
263 @cvar PERMIT: "Permit" decision type instance
264 @type PERMIT: PermitDecision
265
266 @cvar DENY: "Deny" decision type instance
267 @type DENY: DenyDecision
268
269 @cvar INDETERMINATE: "Indeterminate" decision type instance
270 @type INDETERMINATE: IndeterminateDecision
271
272 @cvar NOT_APPLICABLE: "NotApplicable" decision type instance
273 @type NOT_APPLICABLE: NotApplicableDecision
274
275 @ivar __value: decision value
276 @type __value: string
277 """
278 ELEMENT_LOCAL_NAME = 'Decision'
279
280
281 PERMIT_STR = "Permit"
282
283
284 DENY_STR = "Deny"
285
286
287 INDETERMINATE_STR = "Indeterminate"
288
289
290 NOT_APPLICABLE_STR = "NotApplicable"
291
292 TYPES = (PERMIT_STR, DENY_STR, INDETERMINATE_STR, NOT_APPLICABLE_STR)
293
294
295
296 PERMIT = None
297
298
299
300 DENY = None
301
302
303
304 INDETERMINATE = None
305
306
307
308 NOT_APPLICABLE = None
309
310 __slots__ = ('__value',)
311
315
317 '''Enable pickling
318
319 @return: class instance attributes dictionary
320 @rtype: dict
321 '''
322 _dict = {}
323 for attrName in Decision.__slots__:
324
325
326 if attrName.startswith('__'):
327 attrName = "_Decision" + attrName
328
329 _dict[attrName] = getattr(self, attrName)
330
331 return _dict
332
334 '''Enable pickling
335
336 @param attrDict: class instance attributes dictionary
337 @type attrDict: dict
338 '''
339 for attrName, val in attrDict.items():
340 setattr(self, attrName, val)
341
343 """Set decision value
344
345 @param value: decision value - constrained vocabulary to Decision.TYPES
346 @type value: string or ndg.xacml.core.context.result.Decision
347 @raise AttributeError: invalid decision string value input
348 @raise TypeError: invalid type for input decision value
349 """
350 if isinstance(value, Decision):
351
352 value = str(value)
353
354 elif not isinstance(value, basestring):
355 raise TypeError('Expecting string or Decision instance for '
356 '"value" attribute; got %r instead' % type(value))
357
358 if value not in self.__class__.TYPES:
359 raise AttributeError('Permissable decision types are %r; got '
360 '%r instead' % (Decision.TYPES, value))
361 self.__value = value
362
364 """Get decision value
365
366 @return: decision value
367 @rtype: string
368 """
369 return self.__value
370
371 value = property(fget=_getValue, fset=_setValue, doc="Decision value")
372
374 """represent decision as a string
375
376 @return: decision value
377 @rtype: string
378 """
379 return self.__value
380
382 """Overridden to show the decision value
383
384 @return: decision representation
385 @rtype: string
386 """
387 return "%s = %r" % (super(Decision, self).__repr__(), self.__value)
388
390 """
391 @param decision: decision value to compare with self's
392 @type decision: string or ndg.xacml.core.context.result.Decision
393 @return: True if the decision values match, False otherwise
394 @rtype: bool
395 @raise AttributeError: invalid decision string value input
396 @raise TypeError: invalid type for input decision value
397 """
398 if isinstance(decision, Decision):
399
400 value = decision.value
401
402 elif isinstance(decision, basestring):
403 value = decision
404
405 else:
406 raise TypeError('Expecting string or Decision instance for '
407 'input decision value; got %r instead' % type(value))
408
409 if value not in self.__class__.TYPES:
410 raise AttributeError('Permissable decision types are %r; got '
411 '%r instead' % (Decision.TYPES, value))
412
413 return self.__value == value
414
417 """Permit authorisation Decision"""
418 __slots__ = ()
419
423
425 """Make value read-only
426 @raise AttributeError: value can't be set
427 """
428 raise AttributeError("can't set attribute")
429
432 """Deny authorisation Decision"""
433 __slots__ = ()
434
438
440 """Make value read-only
441 @raise AttributeError: value can't be set
442 """
443 raise AttributeError("can't set attribute")
444
447 """Indeterminate authorisation Decision"""
448 __slots__ = ()
449
453
455 """Make value read-only
456 @raise AttributeError: value can't be set
457 """
458 raise AttributeError("can't set attribute")
459
462 """NotApplicable authorisation Decision"""
463 __slots__ = ()
464
468
470 """Make value read-only
471 @raise AttributeError: value can't be set
472 """
473 raise AttributeError("can't set attribute")
474
475
476
477 Decision.PERMIT = PermitDecision()
478 Decision.DENY = DenyDecision()
479 Decision.INDETERMINATE = IndeterminateDecision()
480 Decision.NOT_APPLICABLE = NotApplicableDecision()
481
482
483 -class Result(XacmlContextBase):
484 """XACML Result type - element in a Response
485
486 @cvar ELEMENT_LOCAL_NAME: XML element local name
487 @type ELEMENT_LOCAL_NAME: string
488
489 @cvar OBLIGATIONS_ELEMENT_LOCAL_NAME: obligations XML element local name
490 @type OBLIGATIONS_ELEMENT_LOCAL_NAME: string
491
492 @cvar RESOURCE_ID_ATTRIB_NAME: resource ID XML attribute name
493 @type RESOURCE_ID_ATTRIB_NAME: string
494
495 @ivar __resourceId: resource id
496 @type __resourceId: None/basestring
497
498 @ivar __decision: decision for this result
499 @type __decision: ndg.xacml.core.context.result.Decision
500
501 @ivar __status: result status
502 @type __status: ndg.xacml.core.context.result.Status
503
504 @ivar __obligations: obligations associated with this result
505 @type __obligations: ndg.xacml.core.obligation.Obligation
506 """
507 __slots__ = ('__resourceId', '__decision', '__status', '__obligations')
508
509 ELEMENT_LOCAL_NAME = 'Result'
510 OBLIGATIONS_ELEMENT_LOCAL_NAME = 'Obligations'
511 RESOURCE_ID_ATTRIB_NAME = 'ResourceId'
512
519
520 @classmethod
526 """Create a result object populated with all it's child elements
527 rather than set to None as is the default from __init__
528
529 @param decision: decision for this result
530 @type decision: ndg.xacml.core.context.result.Decision
531
532 @param resourceId: resource id for associated resource
533 @type resourceId: basestring
534
535 @param obligations: obligations associated with this result
536 @type obligations: None/ndg.xacml.core.obligation.Obligation
537
538 @param kw: keywords for status attribute initialisation
539 @type kw: dict
540
541 @return: new result object with all its child attributes created
542 @rtype: ndg.xacml.core.context.result.Result
543 """
544 result = cls()
545 result.decision = Decision()
546 result.decision.value = decision
547 result.status = Status.createInitialised(**kw)
548
549 if obligations is not None:
550 result.obligations = obligations
551
552 return result
553
554 @property
556 """Get Result resource Id
557
558 @return: resource Id
559 @rtype: basestring
560 """
561 return self.__resourceId
562
563 @resourceId.setter
565 """Set Result resource Id
566
567 @param value: resource Id
568 @type value: basestring
569 @raise TypeError: incorrect type for input
570 """
571 if not isinstance(value, basestring):
572 raise TypeError('Expecting %r type for "resourceId" '
573 'result; got %r' % (basestring, type(value)))
574
575 self.__resourceId = value
576
577 @property
579 """Get Result decision
580
581 @return: decision for this result
582 @rtype: ndg.xacml.core.context.result.Decision
583 """
584 return self.__decision
585
586 @decision.setter
588 """Set Request decision
589
590 @param value: decision for this result
591 @type value: ndg.xacml.core.context.result.Decision
592 @raise TypeError: incorrect type for input
593 """
594 if not isinstance(value, Decision):
595 raise TypeError('Expecting %r type for result "decision" '
596 'attribute; got %r' % (Decision, type(value)))
597 self.__decision = value
598
599 @property
601 """Get Result status
602
603 @return: status for this result
604 @rtype: ndg.xacml.core.context.result.Status
605 """
606 return self.__status
607
608 @status.setter
610 """Set Result status
611
612 @param value: status for this result
613 @type value: ndg.xacml.core.context.result.Status
614 @raise TypeError: incorrect type for input
615 """
616 if not isinstance(value, Status):
617 raise TypeError('Expecting %r type for result "status" '
618 'attribute; got %r' % (Status, type(value)))
619
620 self.__status = value
621
622 @property
624 """Get Result obligations
625
626 @return: obligations associated with this result
627 @rtype: ndg.xacml.core.obligations.Obligations
628 """
629 return self.__obligations
630
631 @obligations.setter
633 """Set Result obligations
634
635 @param value: obligations associated with this result
636 @type value: ndg.xacml.core.obligations.Obligations
637
638 @raise TypeError: incorrect type for input
639 """
640 if not isinstance(value, Obligation):
641 raise TypeError('Expecting %r type for result "obligations" '
642 'attribute; got %r' % (Obligation, type(value)))
643
644 self.__obligations = value
645
647 '''Enable pickling
648
649 @return: object's attribute dictionary
650 @rtype: dict
651 '''
652 _dict = super(Result, self).__getstate__()
653 for attrName in Result.__slots__:
654
655
656 if attrName.startswith('__'):
657 attrName = "_Result" + attrName
658
659 _dict[attrName] = getattr(self, attrName)
660
661 return _dict
662