Package ndg :: Package xacml :: Package core :: Package context :: Module result
[hide private]

Source Code for Module ndg.xacml.core.context.result

  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 
17 18 19 -class StatusCode(XacmlContextBase):
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
63 - def __init__(self, **kw):
64 super(StatusCode, self).__init__(**kw) 65 66 # Value attribute URI. 67 self.__value = None 68 69 # Nested secondary StatusCode child element. 70 self.__childStatusCode = None
71
72 - def _getStatusCode(self):
73 '''@return: child status code 74 @rtype: ndg.xacml.core.result.StatusCode 75 ''' 76 return self.__childStatusCode
77
78 - def _setStatusCode(self, value):
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
92 - def _getValue(self):
93 '''@return: status code value 94 @rtype: basestring 95 ''' 96 return self.__value
97
98 - def _setValue(self, value):
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 # Local Name of Status. 130 ELEMENT_LOCAL_NAME = "Status" 131 132 __slots__ = ('__statusCode', '__statusMessage', '__statusDetail', ) 133
134 - def __init__(self, **kw):
135 super(Status, self).__init__(**kw) 136 137 # StatusCode element. 138 self.__statusCode = None 139 140 # StatusMessage element. 141 self.__statusMessage = None 142 143 # StatusDetail element. 144 self.__statusDetail = None
145 146 @classmethod
147 - def createInitialised(cls, code=StatusCode.OK, message='', detail=''):
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
167 - def _getStatusCode(self):
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
176 - def _setStatusCode(self, value):
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
193 - def _getStatusMessage(self):
194 ''' 195 Gets the Message of this Status. 196 197 @return: Status StatusMessage 198 @rtype: basestring 199 ''' 200 return self.__statusMessage
201
202 - def _setStatusMessage(self, value):
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
219 - def _getStatusDetail(self):
220 ''' 221 Gets the Detail of this Status. 222 223 @return: Status detail 224 @rtype: any 225 ''' 226 return self.__statusDetail
227
228 - def _setStatusDetail(self, value):
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
241 242 -class Decision(object):
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 # "Permit" decision type string 281 PERMIT_STR = "Permit" 282 283 # "Deny" decision type string 284 DENY_STR = "Deny" 285 286 # "Indeterminate" decision type string 287 INDETERMINATE_STR = "Indeterminate" 288 289 # "NotApplicable" decision type string 290 NOT_APPLICABLE_STR = "NotApplicable" 291 292 TYPES = (PERMIT_STR, DENY_STR, INDETERMINATE_STR, NOT_APPLICABLE_STR) 293 294 # "Permit" decision type as an instance of PermitDecision - see 295 # re-assignment later after definition of PermitDecision class 296 PERMIT = None 297 298 # "Deny" decision type as instance of DenyDecision - see 299 # re-assignment later after definition of DenyDecision class 300 DENY = None 301 302 # "Indeterminate" decision type as instance of IndeterminateDecision - see 303 # re-assignment later after definition of IndeterminateDecision class 304 INDETERMINATE = None 305 306 # "NotApplicable" decision type as instance of NotApplicableDecision - see 307 # re-assignment later after definition of NotApplicableDecision class 308 NOT_APPLICABLE = None 309 310 __slots__ = ('__value',) 311
312 - def __init__(self, decision=INDETERMINATE_STR):
313 self.__value = None 314 self.value = decision
315
316 - def __getstate__(self):
317 '''Enable pickling 318 319 @return: class instance attributes dictionary 320 @rtype: dict 321 ''' 322 _dict = {} 323 for attrName in Decision.__slots__: 324 # Ugly hack to allow for derived classes setting private member 325 # variables 326 if attrName.startswith('__'): 327 attrName = "_Decision" + attrName 328 329 _dict[attrName] = getattr(self, attrName) 330 331 return _dict
332
333 - def __setstate__(self, attrDict):
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
342 - def _setValue(self, value):
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 # Cast to string 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
363 - def _getValue(self):
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
373 - def __str__(self):
374 """represent decision as a string 375 376 @return: decision value 377 @rtype: string 378 """ 379 return self.__value
380
381 - def __repr__(self):
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
389 - def __eq__(self, decision):
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 # Cast to string 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
415 416 -class PermitDecision(Decision):
417 """Permit authorisation Decision""" 418 __slots__ = () 419
420 - def __init__(self):
421 """Initialise set with Permit value""" 422 super(PermitDecision, self).__init__(Decision.PERMIT_STR)
423
424 - def _setValue(self):
425 """Make value read-only 426 @raise AttributeError: value can't be set 427 """ 428 raise AttributeError("can't set attribute")
429
430 431 -class DenyDecision(Decision):
432 """Deny authorisation Decision""" 433 __slots__ = () 434
435 - def __init__(self):
436 """Initialise set with deny value""" 437 super(DenyDecision, self).__init__(Decision.DENY_STR)
438
439 - def _setValue(self, value):
440 """Make value read-only 441 @raise AttributeError: value can't be set 442 """ 443 raise AttributeError("can't set attribute")
444
445 446 -class IndeterminateDecision(Decision):
447 """Indeterminate authorisation Decision""" 448 __slots__ = () 449
450 - def __init__(self):
451 """Initialise set with indeterminate value""" 452 super(IndeterminateDecision, self).__init__(Decision.INDETERMINATE_STR)
453
454 - def _setValue(self, value):
455 """Make value read-only 456 @raise AttributeError: value can't be set 457 """ 458 raise AttributeError("can't set attribute")
459
460 461 -class NotApplicableDecision(Decision):
462 """NotApplicable authorisation Decision""" 463 __slots__ = () 464
465 - def __init__(self):
466 """Initialise set with not applicable value""" 467 super(NotApplicableDecision, self).__init__(Decision.NOT_APPLICABLE_STR)
468
469 - def _setValue(self, value):
470 """Make value read-only 471 @raise AttributeError: value can't be set 472 """ 473 raise AttributeError("can't set attribute")
474 475 476 # Add instances of each for convenience 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
513 - def __init__(self):
514 super(Result, self).__init__() 515 self.__decision = None 516 self.__status = None 517 self.__resourceId = None 518 self.__obligations = None
519 520 @classmethod
521 - def createInitialised(cls, 522 decision=Decision.NOT_APPLICABLE, 523 resourceId='', 524 obligations=None, 525 **kw):
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
555 - def resourceId(self):
556 """Get Result resource Id 557 558 @return: resource Id 559 @rtype: basestring 560 """ 561 return self.__resourceId
562 563 @resourceId.setter
564 - def resourceId(self, value):
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
578 - def decision(self):
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
587 - def decision(self, value):
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
600 - def status(self):
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
609 - def status(self, value):
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
623 - def obligations(self):
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
632 - def obligations(self, value):
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
646 - def __getstate__(self):
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 # Ugly hack to allow for derived classes setting private member 655 # variables 656 if attrName.startswith('__'): 657 attrName = "_Result" + attrName 658 659 _dict[attrName] = getattr(self, attrName) 660 661 return _dict
662