Package ndg :: Package xacml :: Package parsers :: Package etree :: Module context
[hide private]

Source Code for Module ndg.xacml.parsers.etree.context

  1  """NDG XACML module for context types 
  2   
  3  NERC DataGrid 
  4  """ 
  5  __author__ = "R B Wilkinson" 
  6  __date__ = "23/12/11" 
  7  __copyright__ = "(C) 2011 Science and Technology Facilities Council" 
  8  __license__ = "BSD - see LICENSE file in top-level directory" 
  9  __contact__ = "Philip.Kershaw@stfc.ac.uk" 
 10  __revision__ = "$Id$" 
 11   
 12  import logging 
 13  log = logging.getLogger(__name__) 
 14   
 15  from ndg.xacml import importElementTree 
 16  ElementTree = importElementTree() 
 17   
 18  from ndg.xacml.core import Identifiers 
 19  from ndg.xacml.core.attribute import Attribute 
 20  from ndg.xacml.core.attributevalue import AttributeValueClassFactory 
 21  from ndg.xacml.core.context import XacmlContextBase 
 22  from ndg.xacml.core.context.action import Action 
 23  from ndg.xacml.core.context.environment import Environment 
 24  from ndg.xacml.core.context.request import Request 
 25  from ndg.xacml.core.context.resource import Resource 
 26  from ndg.xacml.core.context.response import Response 
 27  from ndg.xacml.core.context.result import Decision, Result 
 28  from ndg.xacml.core.context.subject import Subject 
 29  from ndg.xacml.parsers import XMLParseError 
 30  import ndg.xacml.parsers.etree as etree 
 31  from ndg.xacml.parsers.etree import QName, getElementChildren 
32 33 34 -class RequestElementTree(Request):
35 """ElementTree based parser for XACML Request element 36 """ 37 @classmethod
38 - def toXML(cls, request):
39 """Create an XML representation of the input XACML Request object 40 41 @type request: ndg.xacml.core.context.request.Request 42 @param request: XACML request object 43 @rtype: ElementTree.Element 44 @return: ElementTree element containing the request 45 """ 46 if not isinstance(request, Request): 47 raise TypeError("Expecting %r class got %r" % (Request, 48 type(request))) 49 50 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 51 cls.ELEMENT_LOCAL_NAME)) 52 elem = etree.makeEtreeElement(tag, 53 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 54 XacmlContextBase.XACML_2_0_CONTEXT_NS) 55 56 # Subjects (should be at least one) 57 for subject in request.subjects: 58 subjectElem = SubjectElementTree.toXML(subject) 59 elem.append(subjectElem) 60 61 # Resource (should be at least one) 62 for resource in request.resources: 63 resourceElem = ResourceElementTree.toXML(resource) 64 elem.append(resourceElem) 65 66 # Action (should be one) 67 actionElem = ActionElementTree.toXML(request.action) 68 elem.append(actionElem) 69 70 # Environment (should be one) 71 environmentElem = EnvironmentElementTree.toXML(request.environment) 72 elem.append(environmentElem) 73 74 return elem
75 76 @classmethod
77 - def fromXML(cls, elem):
78 """Parse an ElementTree XACML Request element into a 79 Request object 80 81 @type elem: ElementTree.Element 82 @param elem: ElementTree element containing the request 83 @rtype: ndg.xacml.core.context.request.Request 84 @return: Request object 85 """ 86 request = Request() 87 88 # Set a reference to the ElementTree element for use by 89 # AttributeSelectors. The context element for an AttributeSelector is 90 # always the request, so this is the only element for this is needed. 91 request.elem = elem 92 93 localName = QName.getLocalPart(elem.tag) 94 if localName != cls.ELEMENT_LOCAL_NAME: 95 raise XMLParseError('No "%s" element found' % 96 cls.ELEMENT_LOCAL_NAME) 97 98 # Parse sub-elements 99 for childElem in getElementChildren(elem): 100 localName = QName.getLocalPart(childElem.tag) 101 102 if localName == Subject.ELEMENT_LOCAL_NAME: 103 subject = SubjectElementTree.fromXML(childElem) 104 request.subjects.append(subject) 105 106 elif localName == Resource.ELEMENT_LOCAL_NAME: 107 resource = ResourceElementTree.fromXML(childElem) 108 request.resources.append(resource) 109 110 elif localName == Action.ELEMENT_LOCAL_NAME: 111 request.action = ActionElementTree.fromXML(childElem) 112 113 elif localName == Environment.ELEMENT_LOCAL_NAME: 114 request.environment = EnvironmentElementTree.fromXML(childElem) 115 116 else: 117 raise XMLParseError("XACML context Request child element name %r" 118 " not recognised" % localName) 119 120 return request
121
122 -class SubjectElementTree(Subject):
123 """ElementTree based parser for XACML Request element 124 """ 125 @classmethod
126 - def toXML(cls, subject):
127 """Create an XML representation of the input XACML Subject object 128 129 @type subject: ndg.xacml.core.context.subject.Subject 130 @param subject: XACML subject object 131 @rtype: ElementTree.Element 132 @return: ElementTree element containing the subject 133 """ 134 if not isinstance(subject, Subject): 135 raise TypeError("Expecting %r class got %r" % (Subject, 136 type(subject))) 137 138 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 139 cls.ELEMENT_LOCAL_NAME)) 140 elem = etree.makeEtreeElement(tag, 141 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 142 XacmlContextBase.XACML_2_0_CONTEXT_NS) 143 144 for attribute in subject.attributes: 145 attributeElem = AttributeElementTree.toXML(attribute) 146 elem.append(attributeElem) 147 148 return elem
149 150 @classmethod
151 - def fromXML(cls, elem):
152 """Parse an ElementTree XACML Subject element into a 153 Subject object 154 155 @type elem: ElementTree.Element 156 @param elem: ElementTree element containing the subject 157 @rtype: ndg.xacml.core.context.subject.Subject 158 @return: Subject object 159 """ 160 localName = QName.getLocalPart(elem.tag) 161 if localName != cls.ELEMENT_LOCAL_NAME: 162 raise XMLParseError('No "%s" element found' % 163 cls.ELEMENT_LOCAL_NAME) 164 165 subject = Subject() 166 167 subject.subjectCategory = elem.get(cls.SUBJECT_CATEGORY_ATTRIB_NAME, 168 Identifiers.SubjectCategory.ACCESS_SUBJECT) 169 170 # Parse sub-elements 171 for childElem in getElementChildren(elem): 172 localName = QName.getLocalPart(childElem.tag) 173 if localName == Attribute.ELEMENT_LOCAL_NAME: 174 attribute = AttributeElementTree.fromXML(childElem) 175 subject.attributes.append(attribute) 176 return subject
177
178 -class ResourceElementTree(Resource):
179 """ElementTree based parser for XACML Resource element 180 """ 181 @classmethod
182 - def toXML(cls, resource):
183 """Create an XML representation of the input XACML Resource object 184 185 @type resource: ndg.xacml.core.context.resource.Resource 186 @param resource: XACML resource object 187 @rtype: ElementTree.Element 188 @return: ElementTree element containing the resource 189 """ 190 if not isinstance(resource, Resource): 191 raise TypeError("Expecting %r class got %r" % (Resource, 192 type(resource))) 193 194 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 195 cls.ELEMENT_LOCAL_NAME)) 196 elem = etree.makeEtreeElement(tag, 197 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 198 XacmlContextBase.XACML_2_0_CONTEXT_NS) 199 200 # ResourceContent can have any attributes and contains a sequence of 201 # any elements. 202 # TODO Is this meant to be an element already? Assume so. 203 # If not, need a representation of an element that includes its 204 # attributes and child elements. 205 if resource.resourceContent is not None: 206 if not ElementTree.iselement(resource.resourceContent): 207 raise TypeError("Expecting ElementTree element got %r" % 208 type(resource.resourceContent)) 209 elem.append(resource.resourceContent) 210 211 for attribute in resource.attributes: 212 attributeElem = AttributeElementTree.toXML(attribute) 213 elem.append(attributeElem) 214 215 return elem
216 217 @classmethod
218 - def fromXML(cls, elem):
219 """Parse an ElementTree XACML Resource element into a 220 Resource object 221 222 @type elem: ElementTree.Element 223 @param elem: ElementTree element containing the resource 224 @rtype: ndg.xacml.core.context.resource.Resource 225 @return: Resource object 226 """ 227 localName = QName.getLocalPart(elem.tag) 228 if localName != cls.ELEMENT_LOCAL_NAME: 229 raise XMLParseError('No "%s" element found' % 230 cls.ELEMENT_LOCAL_NAME) 231 232 resource = Resource() 233 234 # Parse sub-elements 235 for childElem in getElementChildren(elem): 236 localName = QName.getLocalPart(childElem.tag) 237 if localName == Attribute.ELEMENT_LOCAL_NAME: 238 attribute = AttributeElementTree.fromXML(childElem) 239 resource.attributes.append(attribute) 240 elif localName == cls.RESOURCE_CONTENT_ELEMENT_LOCAL_NAME: 241 ### TODO Store resource content as subtree. 242 resource.resourceContent = childElem 243 return resource
244
245 -class ActionElementTree(Action):
246 """ElementTree based parser for XACML Action element 247 """ 248 @classmethod
249 - def toXML(cls, action):
250 """Create an XML representation of the input XACML Action object 251 252 @type action: ndg.xacml.core.context.action.Action 253 @param action: XACML action object 254 @rtype: ElementTree.Element 255 @return: ElementTree element containing the action 256 """ 257 if not isinstance(action, Action): 258 raise TypeError("Expecting %r class got %r" % (Action, 259 type(action))) 260 261 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 262 cls.ELEMENT_LOCAL_NAME)) 263 elem = etree.makeEtreeElement(tag, 264 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 265 XacmlContextBase.XACML_2_0_CONTEXT_NS) 266 267 for attribute in action.attributes: 268 attributeElem = AttributeElementTree.toXML(attribute) 269 elem.append(attributeElem) 270 271 return elem
272 273 @classmethod
274 - def fromXML(cls, elem):
275 """Parse an ElementTree XACML Action element into a 276 Action object 277 278 @type elem: ElementTree.Element 279 @param elem: ElementTree element containing the action 280 @rtype: ndg.xacml.core.context.action.Action 281 @return: Action object 282 """ 283 localName = QName.getLocalPart(elem.tag) 284 if localName != cls.ELEMENT_LOCAL_NAME: 285 raise XMLParseError('No "%s" element found' % 286 cls.ELEMENT_LOCAL_NAME) 287 288 action = Action() 289 290 # Parse sub-elements 291 for childElem in getElementChildren(elem): 292 localName = QName.getLocalPart(childElem.tag) 293 if localName == Attribute.ELEMENT_LOCAL_NAME: 294 attribute = AttributeElementTree.fromXML(childElem) 295 action.attributes.append(attribute) 296 return action
297
298 -class EnvironmentElementTree(Environment):
299 """ElementTree based parser for XACML Environment element 300 """ 301 @classmethod
302 - def toXML(cls, environment):
303 """Create an XML representation of the input XACML Environment object 304 305 @type environment: ndg.xacml.core.context.environment.Environment 306 @param environment: XACML environment object 307 @rtype: ElementTree.Element 308 @return: ElementTree element containing the environment 309 """ 310 if not isinstance(environment, Environment): 311 raise TypeError("Expecting %r class got %r" % (Environment, 312 type(environment))) 313 314 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 315 cls.ELEMENT_LOCAL_NAME)) 316 elem = etree.makeEtreeElement(tag, 317 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 318 XacmlContextBase.XACML_2_0_CONTEXT_NS) 319 320 for attribute in environment.attributes: 321 attributeElem = AttributeElementTree.toXML(attribute) 322 elem.append(attributeElem) 323 324 return elem
325 326 @classmethod
327 - def fromXML(cls, elem):
328 """Parse an ElementTree XACML Environment element into a 329 Environment object 330 331 @type elem: ElementTree.Element 332 @param elem: ElementTree element containing the environment 333 @rtype: ndg.xacml.core.context.environment.Environment 334 @return: Environment object 335 """ 336 localName = QName.getLocalPart(elem.tag) 337 if localName != cls.ELEMENT_LOCAL_NAME: 338 raise XMLParseError('No "%s" element found' % 339 cls.ELEMENT_LOCAL_NAME) 340 341 environment = Environment() 342 343 # Parse sub-elements 344 for childElem in getElementChildren(elem): 345 localName = QName.getLocalPart(childElem.tag) 346 if localName == Attribute.ELEMENT_LOCAL_NAME: 347 attribute = AttributeElementTree.fromXML(childElem) 348 environment.attributes.append(attribute) 349 return environment
350
351 -class AttributeElementTree(Attribute):
352 """ElementTree based parser for XACML Attribute element 353 """ 354 attributeValueClassFactory = AttributeValueClassFactory() 355 @classmethod
356 - def toXML(cls, attribute):
357 """Create an XML representation of the input XACML Attribute object 358 359 @type attribute: ndg.xacml.core.attribute.Attribute 360 @param attribute: XACML attribute object 361 @rtype: ElementTree.Element 362 @return: ElementTree element containing the attribute 363 """ 364 if not isinstance(attribute, Attribute): 365 raise TypeError("Expecting %r class got %r" % (Attribute, 366 type(attribute))) 367 368 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 369 cls.ELEMENT_LOCAL_NAME)) 370 elem = etree.makeEtreeElement(tag, 371 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 372 XacmlContextBase.XACML_2_0_CONTEXT_NS) 373 374 # Handle attributes. 375 ### TODO Check for mandatory attributes. 376 elem.set(Attribute.ATTRIBUTE_ID_ATTRIB_NAME, attribute.attributeId) 377 elem.set(Attribute.DATA_TYPE_ATTRIB_NAME, attribute.dataType) 378 if attribute.issuer is not None: 379 elem.set(Attribute.ISSUER_ATTRIB_NAME, attribute.issuer) 380 381 # Handle attribute value sub-elements. 382 for attributeValue in attribute.attributeValues: 383 valueTag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 384 Attribute.ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME)) 385 valueElem = etree.makeEtreeElement(valueTag, 386 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 387 Attribute.ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME) 388 valueElem.text = attributeValue.value 389 elem.append(valueElem) 390 ### TODO AttributeValue is a sequence of xs:any with xs:anyAttribute 391 392 return elem
393 394 @classmethod
395 - def fromXML(cls, elem):
396 """Parse an ElementTree XACML Attribute element into a 397 Attribute object 398 399 @type elem: ElementTree.Element 400 @param elem: ElementTree element containing the attribute 401 @rtype: ndg.xacml.core.attribute.Attribute 402 @return: Attribute object 403 """ 404 localName = QName.getLocalPart(elem.tag) 405 if localName != cls.ELEMENT_LOCAL_NAME: 406 raise XMLParseError('No "%s" element found' % 407 cls.ELEMENT_LOCAL_NAME) 408 409 attribute = Attribute() 410 411 # Handle attributes. 412 attribute.attributeId = elem.get(Attribute.ATTRIBUTE_ID_ATTRIB_NAME) 413 attribute.dataType = elem.get(Attribute.DATA_TYPE_ATTRIB_NAME) 414 issuer = elem.get(Attribute.ISSUER_ATTRIB_NAME) 415 if issuer is not None: 416 attribute.issuer = issuer 417 418 # Parse sub-elements 419 if len(elem.getchildren()) == 0: 420 raise XMLParseError("XACML context Attribute element has no " 421 "AttributeValues") 422 AttributeValueClass = cls.attributeValueClassFactory(attribute.dataType) 423 for childElem in getElementChildren(elem): 424 localName = QName.getLocalPart(childElem.tag) 425 426 if localName == Attribute.ATTRIBUTE_VALUE_ELEMENT_LOCAL_NAME: 427 attributeValue = AttributeValueClass(childElem.text) 428 attribute.attributeValues.append(attributeValue) 429 430 else: 431 raise XMLParseError("XACML context Request child element name " 432 "%r not recognised" % localName) 433 return attribute
434
435 -class ResponseElementTree(Response):
436 """ElementTree based parser for XACML Response element 437 """ 438 @classmethod
439 - def toXML(cls, response):
440 """Create an XML representation of the input XACML Response object 441 442 @type response: ndg.xacml.core.context.response.Response 443 @param response: XACML response object 444 @rtype: ElementTree.Element 445 @return: ElementTree element containing the response 446 """ 447 if not isinstance(response, Response): 448 raise TypeError("Expecting %r class got %r" % (Response, 449 type(response))) 450 451 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 452 cls.ELEMENT_LOCAL_NAME)) 453 elem = etree.makeEtreeElement(tag, 454 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 455 XacmlContextBase.XACML_2_0_CONTEXT_NS) 456 457 for result in response.results: 458 resultElem = ResultElementTree.toXML(result) 459 elem.append(resultElem) 460 461 return elem
462 463 @classmethod
464 - def fromXML(cls, elem):
465 """Parse an ElementTree XACML Response element into a 466 Response object 467 468 @type elem: ElementTree.Element 469 @param elem: ElementTree element containing the response 470 @rtype: ndg.xacml.core.context.response.Response 471 @return: Response object 472 """ 473 localName = QName.getLocalPart(elem.tag) 474 if localName != cls.ELEMENT_LOCAL_NAME: 475 raise XMLParseError('No "%s" element found' % 476 cls.ELEMENT_LOCAL_NAME) 477 478 response = Response() 479 480 for childElem in getElementChildren(elem): 481 localName = QName.getLocalPart(childElem.tag) 482 483 if localName == Result.ELEMENT_LOCAL_NAME: 484 result = ResultElementTree.fromXML(childElem) 485 response.results.append(result) 486 else: 487 raise XMLParseError("XACML context Request child element name " 488 "%r not recognised" % localName) 489 return response
490
491 -class ResultElementTree(Result):
492 """ElementTree based parser for XACML Result element 493 """ 494 @classmethod
495 - def toXML(cls, result):
496 """Create an XML representation of the input XACML Result object 497 498 @type result: ndg.xacml.core.context.result.Result 499 @param result: XACML result object 500 @rtype: ElementTree.Element 501 @return: ElementTree element containing the result 502 """ 503 if not isinstance(result, 504 Result): 505 raise TypeError("Expecting %r class got %r" % 506 (Result, 507 type(result))) 508 509 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 510 cls.ELEMENT_LOCAL_NAME)) 511 512 attrib = {} 513 # ResourceId attribute is optional. 514 if result.resourceId is not None: 515 attrib.append[cls.RESOURCE_ID_ATTRIB_NAME] = result.resourceId 516 517 elem = etree.makeEtreeElement(tag, 518 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 519 XacmlContextBase.XACML_2_0_CONTEXT_NS, **attrib) 520 521 decisionElem = DecisionElementTree.toXML(result.decision) 522 elem.append(decisionElem) 523 524 ### TODO Handle status and obligations 525 526 return elem
527 528 @classmethod
529 - def fromXML(cls, elem):
530 """Parse an ElementTree XACML Result element into a 531 Result object 532 533 @type elem: ElementTree.Element 534 @param elem: ElementTree element containing the result 535 @rtype: ndg.xacml.core.context.result.Result 536 @return: Result object 537 """ 538 localName = QName.getLocalPart(elem.tag) 539 if localName != cls.ELEMENT_LOCAL_NAME: 540 raise XMLParseError('No "%s" element found' % 541 cls.ELEMENT_LOCAL_NAME) 542 543 result = Result() 544 545 resourceId = elem.get(Result.RESOURCE_ID_ATTRIB_NAME) 546 if resourceId is not None: 547 result.resourceId = resourceId 548 549 for childElem in getElementChildren(elem): 550 localName = QName.getLocalPart(childElem.tag) 551 552 if localName == Decision.ELEMENT_LOCAL_NAME: 553 decision = DecisionElementTree.fromXML(childElem) 554 result.decision = decision 555 else: 556 raise XMLParseError("XACML context Request child element name " 557 "%r not recognised" % localName) 558 559 ### TODO Handle status and obligations 560 561 return result
562
563 -class DecisionElementTree(Decision):
564 """ElementTree based parser for XACML Decision element 565 """ 566 @classmethod
567 - def toXML(cls, decision):
568 """Create an XML representation of the input XACML Decision object 569 570 @type decision: ndg.xacml.core.context.decision.Decision 571 @param decision: XACML decision object 572 @rtype: ElementTree.Element 573 @return: ElementTree element containing the decision 574 """ 575 if not isinstance(decision, 576 Decision): 577 raise TypeError("Expecting %r class got %r" % 578 (Decision, 579 type(decision))) 580 581 tag = str(QName(XacmlContextBase.XACML_2_0_CONTEXT_NS, 582 cls.ELEMENT_LOCAL_NAME)) 583 584 elem = etree.makeEtreeElement(tag, 585 XacmlContextBase.XACML_2_0_CONTEXT_NS_PREFIX, 586 XacmlContextBase.XACML_2_0_CONTEXT_NS) 587 elem.text = decision.value 588 589 return elem
590 591 @classmethod
592 - def fromXML(cls, elem):
593 """Parse an ElementTree XACML Decision element into a 594 Decision object 595 596 @type elem: ElementTree.Element 597 @param elem: ElementTree element containing the decision 598 @rtype: ndg.xacml.core.context.decision.Decision 599 @return: Decision object 600 """ 601 localName = QName.getLocalPart(elem.tag) 602 if localName != cls.ELEMENT_LOCAL_NAME: 603 raise XMLParseError('No "%s" element found' % 604 cls.ELEMENT_LOCAL_NAME) 605 606 decision = Decision() 607 608 decision.value = elem.text 609 610 return decision
611