Changeset 6553
- Timestamp:
- 10/02/10 17:04:46 (11 years ago)
- Location:
- TI12-security/trunk/ndg_security_saml/saml
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/ndg_security_saml/saml/saml2/core.py
r6547 r6553 322 322 ''' 323 323 raise NotImplementedError() 324 324 325 326 class DecisionType(object): 327 """Define decision types for the authorisation decisions""" 328 329 # "Permit" decision type 330 PERMIT = "Permit" 331 332 # "Deny" decision type 333 DENY = "Deny" 334 335 # "Indeterminate" decision type 336 INDETERMINATE = "Indeterminate" 337 338 TYPES = (PERMIT, DENY, INDETERMINATE) 339 340 __slots__ = ('__value',) 341 342 def __init__(self, decisionType): 343 self.__value = None 344 self.value = decisionType 345 346 def _setValue(self, value): 347 if not isinstance(value, basestring): 348 raise TypeError('Expecting string type for "value" attribute; got ' 349 'instead' % type(value)) 350 351 if value not in DecisionType.TYPES: 352 raise AttributeError('Permissable decision types are %r; got %r ' 353 'instead' % (DecisionType.TYPES, 354 value)) 355 self.__value = value 356 357 def _getValue(self): 358 return self.__value 359 360 value = property(fget=_getValue, fset=_setValue, doc="Decision value") 361 362 def __str__(self): 363 return self.__value 364 325 365 326 366 class AuthzDecisionStatement(Statement): … … 359 399 360 400 # Resource attribute value. 361 self.__resource = None 401 self.__resource = None 402 403 self.__decision = DecisionType(DecisionType.INDETERMINATE) 404 self.__actions = TypedList(Action) 405 self.__evidence = None 362 406 363 407 # Tuning for normalization of resource URIs in property set method … … 454 498 @return: the decision of the authorization request 455 499 ''' 456 r aise NotImplementedError()500 return self.__decision 457 501 458 502 def _setDecision(self, value): … … 462 506 @param value: the decision of the authorization request 463 507 ''' 464 raise NotImplementedError() 508 if not isinstance(value, basestring): 509 raise TypeError('Expecting %r type for "decision" attribute; ' 510 'got instead' % (DecisionType, type(value))) 511 self.__decision = value 465 512 466 513 @property … … 1043 1090 # TODO: Implement AuthnStatement and AuthzDecisionStatement classes 1044 1091 self.__authnStatements = [] 1045 self.__authzDecisionStatements = []1092 self.__authzDecisionStatements = TypedList(AuthzDecisionStatement) 1046 1093 self.__attributeStatements = TypedList(AttributeStatement) 1047 1094 … … 1166 1213 doc="Attribute Assertion advice") 1167 1214 1168 def _get_statements(self): 1169 """Get statements string.""" 1215 @property 1216 def statements(self): 1217 """Attribute Assertion statements""" 1170 1218 return self.__statements 1171 1172 statements = property(fget=_get_statements, 1173 doc="Attribute Assertion statements") 1174 1175 def _get_authnStatements(self): 1176 """Get authnStatements string.""" 1219 1220 @property 1221 def authnStatements(self): 1222 """Attribute Assertion authentication""" 1177 1223 return self.__authnStatements 1178 1179 authnStatements = property(fget=_get_authnStatements, 1180 doc="Attribute Assertion authentication " 1181 "statements") 1182 1183 def _get_authzDecisionStatements(self): 1184 """Get authorisation decision statements.""" 1224 1225 @property 1226 def authzDecisionStatements(self): 1227 """Attribute Assertion authorisation decision statements""" 1185 1228 return self.__authzDecisionStatements 1186 1187 authzDecisionStatements = property(fget=_get_authzDecisionStatements, 1188 doc="Attribute Assertion authorisation " 1189 "decision statements") 1190 1191 def _get_attributeStatements(self): 1192 """Get attributeStatements string.""" 1229 1230 @property 1231 def attributeStatements(self): 1232 """Attribute Assertion attribute statements""" 1193 1233 return self.__attributeStatements 1194 1195 attributeStatements = property(fget=_get_attributeStatements,1196 doc="Attribute Assertion attribute "1197 "statements")1198 1234 1199 1235 … … 1652 1688 UNIX_NS_URI = "urn:oasis:names:tc:SAML:1.0:action:unix" 1653 1689 1690 ACTION_NS_IDENTIFIERS = ( 1691 RWEDC_NS_URI, 1692 RWEDC_NEGATION_NS_URI, 1693 GHPP_NS_URI, 1694 UNIX_NS_URI 1695 ) 1696 1654 1697 # Read action. 1655 1698 READ_ACTION = "Read" … … 1694 1737 HTTP_POST_ACTION = "POST" 1695 1738 1739 ACTION_TYPES = { 1740 RWEDC_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, DELETE_ACTION, 1741 CONTROL_ACTION), 1742 RWEDC_NEGATION_NS_URI: (READ_ACTION, WRITE_ACTION, EXECUTE_ACTION, 1743 DELETE_ACTION, CONTROL_ACTION, NEG_READ_ACTION, 1744 NEG_WRITE_ACTION, NEG_EXECUTE_ACTION, 1745 NEG_CONTROL_ACTION), 1746 GHPP_NS_URI: (HTTP_GET_ACTION, HTTP_HEAD_ACTION, HTTP_PUT_ACTION, 1747 HTTP_POST_ACTION), 1748 1749 # This namespace uses octal bitmask for file permissions 1750 UNIX_NS_URI: () 1751 } 1752 1696 1753 def __init__(self, **kw): 1697 1754 '''Create an authorization action type … … 1699 1756 super(Action, self).__init__(**kw) 1700 1757 1701 # URI of the Namespace of this action 1702 self.__namespace = None 1758 # URI of the Namespace of this action. Default to read/write/negation 1759 # type - 2.7.4.2 SAML 2 Core Spec. 15 March 2005 1760 self.__namespace = Action.RWEDC_NEGATION_NS_URI 1703 1761 1704 1762 #Value value 1705 1763 self.__action = None 1706 1764 1765 self.__actionTypes = Action.ACTION_TYPES 1766 1767 def _getActionTypes(self): 1768 return self.__actionTypes 1769 1770 def _setActionTypes(self, value): 1771 if not isinstance(value, dict): 1772 raise TypeError('Expecting list or tuple type for "actionTypes" ' 1773 'attribute; got %r' % type(value)) 1774 1775 for k, v in value.items(): 1776 if not isinstance(v, (tuple, type(None))): 1777 raise TypeError('Expecting None or tuple type for ' 1778 '"actionTypes" dictionary values; got %r for ' 1779 '%r key' % (type(value), k)) 1780 self.__actionTypes = value 1781 1782 actionTypes = property(_getActionTypes, 1783 _setActionTypes, 1784 doc="Restrict vocabulary of action types") 1785 1707 1786 def _getNamespace(self): 1708 1787 ''' 1709 gets the namespace scope of the specified value.1710 1711 @return: the namespace scope of the specified value1788 gets the namespace scope of the specified value. 1789 1790 @return: the namespace scope of the specified value 1712 1791 ''' 1713 1792 return self.__namespace … … 1715 1794 def _setNamespace(self, value): 1716 1795 ''' 1717 Sets the namespace scope of the specified value.1718 1719 @param value: the namespace scope of the specified value1796 Sets the namespace scope of the specified value. 1797 1798 @param value: the namespace scope of the specified value 1720 1799 ''' 1721 1800 if not isinstance(value, basestring): 1722 1801 raise TypeError('Expecting string type for "namespace" ' 1723 1802 'attribute; got %r' % type(value)) 1803 1804 if value not in self.__actionTypes.keys(): 1805 raise AttributeError('"namespace" action type %r not recognised. ' 1806 'It must be one of these action types: %r' % 1807 self.__actionNsIdentifiers) 1808 1724 1809 self.__namespace = value 1725 1810 … … 1738 1823 Sets the URI of the action to be performed. 1739 1824 1740 @param value: the URI of thevalue to be performed 1741 ''' 1742 if not isinstance(value, basestring): 1743 raise TypeError('Expecting string type for "action" ' 1825 @param value: the URI of the value to be performed 1826 ''' 1827 # int and oct allow for UNIX file permissions action type 1828 if not isinstance(value, (basestring, int)): 1829 raise TypeError('Expecting string or int type for "action" ' 1744 1830 'attribute; got %r' % type(value)) 1831 1832 # Default to read/write/negation type - 2.7.4.2 SAML 2 Core Spec. 1833 # 15 March 2005 1834 allowedActions = self.__actionTypes.get(self.__namespace, 1835 Action.RWEDC_NEGATION_NS_URI) 1836 1837 # Only apply restriction for action type that has a restricted 1838 # vocabulary - UNIX type is missed out of this because its an octal 1839 # mask 1840 if len(allowedActions) > 0 and value not in allowedActions: 1841 raise AttributeError('%r action not recognised; known actions for ' 1842 'the %r namespace identifier are: %r. ' 1843 'If this is not as expected make sure to set ' 1844 'the "namespace" attribute to an alternative ' 1845 'value first or override completely by ' 1846 'explicitly setting the "allowTypes" ' 1847 'attribute' % 1848 (value, self.__namespace, allowedActions)) 1745 1849 self.__value = value 1746 1850 -
TI12-security/trunk/ndg_security_saml/saml/test/test_saml.py
r6547 r6553 22 22 23 23 from saml.saml2.core import (SAMLVersion, Attribute, AttributeStatement, 24 A ssertion, AttributeQuery, Response, Issuer,25 Subject, NameID, StatusCode,24 AuthzDecisionStatement, Assertion, AttributeQuery, 25 Response, Issuer, Subject, NameID, StatusCode, 26 26 StatusMessage, Status, Conditions, 27 27 XSStringAttributeValue, Action, … … 196 196 for action, namespace in actions: 197 197 authzDecisionQuery.actions.append(Action()) 198 authzDecisionQuery.actions[-1].namespace = namespace 198 199 authzDecisionQuery.actions[-1].value = action 199 authzDecisionQuery.actions[-1].namespace = namespace200 200 201 201 return authzDecisionQuery … … 210 210 RESOURCE_URI = SAMLUtil.RESOURCE_URI 211 211 212 def _createA ssertionHelper(self):212 def _createAttributeAssertionHelper(self): 213 213 samlUtil = SAMLUtil() 214 214 … … 237 237 def test01CreateAssertion(self): 238 238 239 assertion = self._createA ssertionHelper()239 assertion = self._createAttributeAssertionHelper() 240 240 241 241 … … 254 254 255 255 def test02ParseAssertion(self): 256 assertion = self._createA ssertionHelper()256 assertion = self._createAttributeAssertionHelper() 257 257 258 258 # Create ElementTree Assertion Element … … 327 327 print("_"*80) 328 328 329 def test05Create Response(self):329 def test05CreateAttributeQueryResponse(self): 330 330 response = Response() 331 331 response.issueInstant = datetime.utcnow() … … 347 347 response.status.statusMessage.value = "Response created successfully" 348 348 349 assertion = self._createA ssertionHelper()349 assertion = self._createAttributeAssertionHelper() 350 350 351 351 # Add a conditions statement for a validity of 8 hours … … 407 407 408 408 authzDecisionQuery.actions.append(Action()) 409 authzDecisionQuery.actions[0].namespace = Action.GHPP_NS_URI 409 410 authzDecisionQuery.actions[0].value = Action.HTTP_GET_ACTION 410 authzDecisionQuery.actions[0].namespace = Action.GHPP_NS_URI411 411 412 412 self.assert_( … … 414 414 self.assert_( 415 415 authzDecisionQuery.actions[0].namespace == Action.GHPP_NS_URI) 416 417 # Try out the restricted vocabulary 418 try: 419 authzDecisionQuery.actions[0].value = "delete everything" 420 self.fail("Expecting AttributeError raised for incorrect action " 421 "setting.") 422 except AttributeError, e: 423 print("Caught incorrect action type setting: %s" % e) 424 425 authzDecisionQuery.actions[0].actionTypes = {'urn:malicious': 426 ("delete everything",)} 427 428 # Try again now that the actipn types have been adjusted 429 authzDecisionQuery.actions[0].namespace = 'urn:malicious' 430 authzDecisionQuery.actions[0].value = "delete everything" 416 431 417 432 def test07SerializeAuthzDecisionQuery(self): … … 471 486 self.assert_(authzDecisionQuery2.evidence is None) 472 487 488 489 def test05CreateAuthzDecisionQueryResponse(self): 490 response = Response() 491 response.issueInstant = datetime.utcnow() 492 493 # Make up a request ID that this response is responding to 494 response.inResponseTo = str(uuid4()) 495 response.id = str(uuid4()) 496 response.version = SAMLVersion(SAMLVersion.VERSION_20) 497 498 response.issuer = Issuer() 499 response.issuer.format = Issuer.X509_SUBJECT 500 response.issuer.value = \ 501 SAMLTestCase.ISSUER_DN 502 503 response.status = Status() 504 response.status.statusCode = StatusCode() 505 response.status.statusCode.value = StatusCode.SUCCESS_URI 506 response.status.statusMessage = StatusMessage() 507 response.status.statusMessage.value = "Response created successfully" 508 509 assertion = Assertion() 510 authzDecisionStatement = AuthzDecisionStatement() 511 authzDecisionStatement.resource = SAMLTestCase.RESOURCE_URI 512 authzDecisionStatement.actions.append(Action()) 513 authzDecisionStatement.actions[-1].namespace = Action.GHPP_NS_URI 514 authzDecisionStatement.actions[-1].value = Action.HTTP_GET_ACTION 515 assertion.authzDecisionStatements.append(authzDecisionStatement) 516 517 # assertion.subject = Subject() 518 # assertion.subject.nameID = NameID() 519 # assertion.subject.nameID.format = SAMLTestCase.NAMEID_FORMAT 520 # assertion.subject.nameID.value = SAMLTestCase.NAMEID_VALUE 521 # 522 # assertion.issuer = Issuer() 523 # assertion.issuer.format = Issuer.X509_SUBJECT 524 # assertion.issuer.value = SAMLTestCase.ISSUER_DN 525 526 response.assertions.append(assertion) 527 528 # Create ElementTree Assertion Element 529 responseElem = ResponseElementTree.toXML(response) 530 531 self.assert_(iselement(responseElem)) 532 533 # Serialise to output 534 xmlOutput = prettyPrint(responseElem) 535 self.assert_(len(xmlOutput)) 536 print("\n"+"_"*80) 537 print(xmlOutput) 538 print("_"*80) 539 473 540 474 541 if __name__ == "__main__": -
TI12-security/trunk/ndg_security_saml/saml/xml/etree.py
r6547 r6553 43 43 AuthzDecisionQuery, Subject, NameID, Issuer, 44 44 Response, Status, StatusCode, StatusMessage, 45 StatusDetail, Advice, Action, 45 StatusDetail, Advice, Action, Evidence, 46 46 XSStringAttributeValue) 47 47 … … 371 371 372 372 for authzDecisionStatement in assertion.authzDecisionStatements: 373 raise NotImplementedError("Assertion Authorisation Decision " 374 "Statement creation is not implemented") 373 authzDecisionStatementElem = AuthzDecisionStatementElementTree.toXML( 374 authzDecisionStatement, 375 **authzDecisionValueElementTreeFactoryKw) 376 elem.append(authzDecisionStatementElem) 375 377 376 378 for attributeStatement in assertion.attributeStatements: … … 417 419 attributeValues.append(attributeValue) 418 420 419 assertion = Assertion()421 assertion = cls() 420 422 assertion.version = SAMLVersion(attributeValues[0]) 421 423 if assertion.version != SAMLVersion.VERSION_20: … … 451 453 "parsing is not implemented") 452 454 453 elif localName ==AuthzDecisionStatement.DEFAULT_ELEMENT_LOCAL_NAME:454 raise NotImplementedError("Assertion Authorisation Decision "455 "Statement parsing is not "456 "implemented")455 elif localName == AuthzDecisionStatement.DEFAULT_ELEMENT_LOCAL_NAME: 456 authzDecisionStatement = \ 457 AuthzDecisionStatementElementTree.fromXML(childElem) 458 assertion.authzDecisionStatements.append(authzDecisionStatement) 457 459 458 460 elif localName == AttributeStatement.DEFAULT_ELEMENT_LOCAL_NAME: … … 463 465 else: 464 466 raise XMLTypeParseError('Assertion child element name "%s" ' 465 467 'not recognised' % localName) 466 468 467 469 return assertion … … 533 535 534 536 return attributeStatement 537 538 539 class AuthzDecisionStatementElementTree(AuthzDecisionStatement): 540 """ElementTree XML representation of AuthzDecisionStatement""" 541 542 @classmethod 543 def toXML(cls, authzDecisionStatement): 544 """Make a tree of a XML elements based on the authzDecision statement 545 546 @type assertion: saml.saml2.core.AuthzDecisionStatement 547 @param assertion: AuthzDecision Statement to be represented as an 548 ElementTree Element 549 factory 550 @rtype: ElementTree.Element 551 @return: ElementTree Element 552 """ 553 if not isinstance(authzDecisionStatement, AuthzDecisionStatement): 554 raise TypeError("Expecting %r type got: %r" % 555 (AuthzDecisionStatement, authzDecisionStatement)) 556 557 if not authzDecisionStatement.resource: 558 raise AttributeError("Resource for AuthzDecisionStatement is not " 559 "set") 560 561 attrib = { 562 cls.DECISION_ATTRIB_NAME: authzDecisionStatement.decision, 563 cls.RESOURCE_ATTRIB_NAME: authzDecisionStatement.resource 564 } 565 566 tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME)) 567 elem = ElementTree.Element(tag, **attrib) 568 ElementTree._namespace_map[cls.DEFAULT_ELEMENT_NAME.namespaceURI 569 ] = cls.DEFAULT_ELEMENT_NAME.prefix 570 571 for action in authzDecisionStatement.actions: 572 # Factory enables support for multiple authzDecision types 573 actionElem = ActionElementTree.toXML(action) 574 elem.append(actionElem) 575 576 if (authzDecisionStatement.evidence and 577 len(authzDecisionStatement.evidence.values) > 0): 578 raise NotImplementedError("authzDecisionStatementElementTree does " 579 "not currently support the Evidence type") 580 581 return elem 582 583 @classmethod 584 def fromXML(cls, elem, **authzDecisionValueElementTreeFactoryKw): 585 """Parse an ElementTree SAML AuthzDecisionStatement element into an 586 AuthzDecisionStatement object 587 588 @type elem: ElementTree.Element 589 @param elem: ElementTree element containing the AuthzDecisionStatement 590 @type authzDecisionValueElementTreeFactoryKw: dict 591 @param authzDecisionValueElementTreeFactoryKw: keywords for AuthzDecisionValue 592 factory 593 @rtype: saml.saml2.core.AuthzDecisionStatement 594 @return: AuthzDecision Statement""" 595 596 if not ElementTree.iselement(elem): 597 raise TypeError("Expecting %r input type for parsing; got %r" % 598 (ElementTree.Element, elem)) 599 600 localName = QName.getLocalPart(elem.tag) 601 if localName != cls.DEFAULT_ELEMENT_LOCAL_NAME: 602 raise XMLTypeParseError("No \"%s\" element found" % 603 cls.DEFAULT_ELEMENT_LOCAL_NAME) 604 605 606 authzDecisionStatement = cls() 607 608 for childElem in elem: 609 localName = QName.getLocalPart(childElem.tag) 610 611 if localName == Action.DEFAULT_ELEMENT_LOCAL_NAME: 612 action = ActionElementTree.fromXML(childElem) 613 authzDecisionStatement.actions.append(action) 614 615 elif localName == Evidence.DEFAULT_ELEMENT_LOCAL_NAME: 616 raise NotImplementedError("XML parse of %s element is not " 617 "implemented" % 618 Evidence.DEFAULT_ELEMENT_LOCAL_NAME) 619 else: 620 raise XMLTypeParseError("AuthzDecisionStatement child element " 621 "name %r not recognised" % localName) 622 623 return authzDecisionStatement 535 624 536 625
Note: See TracChangeset
for help on using the changeset viewer.