diff --git a/tests/test_0_saml.py b/tests/test_0_saml.py new file mode 100644 index 0000000..c62a6e6 --- /dev/null +++ b/tests/test_0_saml.py @@ -0,0 +1,893 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009 Umeå University. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for saml2.saml""" + +__author__ = 'roland.hedberg@adm.umu.se (Roland Hedberg)' + +try: + from xml.etree import ElementTree +except ImportError: + from elementtree import ElementTree +import saml2 +from saml2 import saml +import saml2_data, ds_data +import xmldsig as ds + +class TestNameID: + + def setup_class(self): + self.name_id = saml.NameID() + + def testEmptyExtensionsList(self): + """Test if NameID has empty extensions list""" + assert isinstance(self.name_id.extension_elements, list) + assert len(self.name_id.extension_elements) == 0 + + def testFormatAttribute(self): + """Test for Format attribute accessors""" + self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS + assert self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert len(self.name_id.extension_elements) == 0 + new_name_id = saml.name_id_from_string(self.name_id.to_string()) + assert len(new_name_id.extension_elements) == 0 + + self.name_id.extension_elements.append(saml2.ExtensionElement( + 'foo', text='bar')) + assert len(self.name_id.extension_elements) == 1 + assert self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS + + def testNameIDText(self): + """Test text value of NameID element""" + self.name_id.text = "tmatsuo@example.com" + assert self.name_id.text == "tmatsuo@example.com" + + def testSPProvidedID(self): + """Test for SPProvidedID attribute accessors""" + self.name_id.sp_provided_id = "provided id" + assert self.name_id.sp_provided_id == "provided id" + + def testEmptyNameIDToAndFromStringMatch(self): + """Test name_id_from_string() with empty NameID""" + string_from_name_id = self.name_id.to_string() + new_name_id = saml.name_id_from_string(string_from_name_id) + string_from_new_name_id = new_name_id.to_string() + assert string_from_name_id == string_from_new_name_id + + def testNameIDToAndFromStringMatch(self): + """Test name_id_from_string() with data""" + self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS + self.name_id.text = "tmatsuo@example.com" + self.name_id.name_qualifier = "name_qualifier" + self.name_id.sp_name_qualifier = "sp_name_qualifier" + string_from_name_id = self.name_id.to_string() + new_name_id = saml.name_id_from_string(string_from_name_id) + assert new_name_id.name_qualifier == "name_qualifier" + assert new_name_id.sp_name_qualifier == "sp_name_qualifier" + string_from_new_name_id = new_name_id.to_string() + assert string_from_name_id == string_from_new_name_id + + def testExtensionAttributes(self): + """Test extension attributes""" + self.name_id.extension_attributes['hoge'] = 'fuga' + self.name_id.extension_attributes['moge'] = 'muga' + assert self.name_id.extension_attributes['hoge'] == 'fuga' + assert self.name_id.extension_attributes['moge'] == 'muga' + new_name_id = saml.name_id_from_string(self.name_id.to_string()) + assert new_name_id.extension_attributes['hoge'] == 'fuga' + assert new_name_id.extension_attributes['moge'] == 'muga' + + def testname_id_from_string(self): + """Test name_id_from_string() using test data""" + name_id = saml.name_id_from_string(saml2_data.TEST_NAME_ID) + assert name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert name_id.text.strip() == "tmatsuo@example.com" + assert name_id.sp_provided_id == "sp provided id" + + +class TestIssuer: + + def setup_class(self): + self.issuer = saml.Issuer() + + def testIssuerToAndFromString(self): + """Test issuer_from_string()""" + self.issuer.text = "http://www.example.com/test" + self.issuer.name_qualifier = "name_qualifier" + self.issuer.sp_name_qualifier = "sp_name_qualifier" + new_issuer = saml.issuer_from_string(self.issuer.to_string()) + assert self.issuer.text == new_issuer.text + assert self.issuer.name_qualifier == new_issuer.name_qualifier + assert self.issuer.sp_name_qualifier == new_issuer.sp_name_qualifier + assert self.issuer.extension_elements == new_issuer.extension_elements + + def testUsingTestData(self): + """Test issuer_from_string() using test data""" + issuer = saml.issuer_from_string(saml2_data.TEST_ISSUER) + assert issuer.text.strip() == "http://www.example.com/test" + new_issuer = saml.issuer_from_string(issuer.to_string()) + assert issuer.text == new_issuer.text + assert issuer.extension_elements == new_issuer.extension_elements + + +class TestSubjectLocality: + + def setup_class(self): + self.subject_locality = saml.SubjectLocality() + + def testAccessors(self): + """Test for SubjectLocality accessors""" + self.subject_locality.address = "127.0.0.1" + self.subject_locality.dns_name = "localhost" + assert self.subject_locality.address == "127.0.0.1" + assert self.subject_locality.dns_name == "localhost" + new_subject_locality = saml.subject_locality_from_string( + self.subject_locality.to_string()) + assert new_subject_locality.address == "127.0.0.1" + assert new_subject_locality.dns_name == "localhost" + + def testUsingTestData(self): + """Test SubjectLocalityFromString() using test data""" + + subject_locality = saml.subject_locality_from_string( + saml2_data.TEST_SUBJECT_LOCALITY) + assert subject_locality.address == "127.0.0.1" + assert subject_locality.dns_name == "localhost" + + new_subject_locality = saml.subject_locality_from_string( + subject_locality.to_string()) + assert new_subject_locality.address == "127.0.0.1" + assert new_subject_locality.dns_name == "localhost" + assert subject_locality.to_string() == new_subject_locality.to_string() + + +class TestAuthnContextClassRef: + + def setup_class(self): + self.authn_context_class_ref = saml.AuthnContextClassRef() + self.text = "http://www.example.com/authnContextClassRef" + + def testAccessors(self): + """Test for AuthnContextClassRef accessors""" + self.authn_context_class_ref.text = self.text + assert self.authn_context_class_ref.text == self.text + new_authn_context_class_ref = saml.authn_context_class_ref_from_string( + self.authn_context_class_ref.to_string()) + assert new_authn_context_class_ref.text == self.text + assert self.authn_context_class_ref.to_string() == \ + new_authn_context_class_ref.to_string() + + def testUsingTestData(self): + """Test authn_context_class_ref_from_string() using test data""" + authn_context_class_ref = saml.authn_context_class_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_CLASS_REF) + assert authn_context_class_ref.text.strip() == self.text + + +class TestAuthnContextDeclRef: + + def setup_class(self): + self.authn_context_decl_ref = saml.AuthnContextDeclRef() + self.ref = "http://www.example.com/authnContextDeclRef" + + def testAccessors(self): + """Test for AuthnContextDeclRef accessors""" + self.authn_context_decl_ref.text = self.ref + assert self.authn_context_decl_ref.text == self.ref + new_authn_context_decl_ref = saml.authn_context_decl_ref_from_string( + self.authn_context_decl_ref.to_string()) + assert new_authn_context_decl_ref.text == self.ref + assert self.authn_context_decl_ref.to_string() == \ + new_authn_context_decl_ref.to_string() + + def testUsingTestData(self): + """Test authn_context_decl_ref_from_string() using test data""" + authn_context_decl_ref = saml.authn_context_decl_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL_REF) + assert authn_context_decl_ref.text.strip() == self.ref + + +class TestAuthnContextDecl: + + def setup_class(self): + self.authn_context_decl = saml.AuthnContextDecl() + self.text = "http://www.example.com/authnContextDecl" + + def testAccessors(self): + """Test for AuthnContextDecl accessors""" + self.authn_context_decl.text = self.text + assert self.authn_context_decl.text == self.text + new_authn_context_decl = saml.authn_context_decl_from_string( + self.authn_context_decl.to_string()) + assert new_authn_context_decl.text == self.text + assert self.authn_context_decl.to_string() == \ + new_authn_context_decl.to_string() + + def testUsingTestData(self): + """Test authn_context_decl_from_string() using test data""" + authn_context_decl = saml.authn_context_decl_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL) + assert authn_context_decl.text.strip() == self.text + + +class TestAuthenticatingAuthority: + + def setup_class(self): + self.authenticating_authority = saml.AuthenticatingAuthority() + self.text = "http://www.example.com/authenticatingAuthority" + + def testAccessors(self): + """Test for AuthenticatingAuthority accessors""" + self.authenticating_authority.text = self.text + assert self.authenticating_authority.text == self.text + new_authenticating_authority = saml.authenticating_authority_from_string( + self.authenticating_authority.to_string()) + assert new_authenticating_authority.text == self.text + assert self.authenticating_authority.to_string() == \ + new_authenticating_authority.to_string() + + def testUsingTestData(self): + """Test authenticating_authority_from_string() using test data""" + authenticating_authority = saml.authenticating_authority_from_string( + saml2_data.TEST_AUTHENTICATING_AUTHORITY) + assert authenticating_authority.text.strip() == self.text + +class TestAuthnContext: + + def setup_class(self): + self.authn_context = saml.AuthnContext() + + def testAccessors(self): + """Test for AuthnContext accessors""" + self.authn_context.authn_context_class_ref = \ + saml.authn_context_class_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_CLASS_REF) + self.authn_context.authn_context_decl_ref = \ + saml.authn_context_decl_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL_REF) + self.authn_context.authn_context_decl = \ + saml.authn_context_decl_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL) + self.authn_context.authenticating_authority.append( + saml.authenticating_authority_from_string( + saml2_data.TEST_AUTHENTICATING_AUTHORITY)) + assert self.authn_context.authn_context_class_ref.text.strip() == \ + "http://www.example.com/authnContextClassRef" + assert self.authn_context.authn_context_decl_ref.text.strip() == \ + "http://www.example.com/authnContextDeclRef" + assert self.authn_context.authn_context_decl.text.strip() == \ + "http://www.example.com/authnContextDecl" + assert self.authn_context.authenticating_authority[0].text.strip() == \ + "http://www.example.com/authenticatingAuthority" + new_authn_context = saml.authn_context_from_string( + self.authn_context.to_string()) + assert self.authn_context.to_string() == new_authn_context.to_string() + + def testUsingTestData(self): + """Test authn_context_from_string() using test data""" + authn_context = saml.authn_context_from_string(saml2_data.TEST_AUTHN_CONTEXT) + assert authn_context.authn_context_class_ref.text.strip() == \ + saml.URN_PASSWORD + + +class TestAuthnStatement: + + def setup_class(self): + self.authn_statem = saml.AuthnStatement() + + def testAccessors(self): + """Test for AuthnStatement accessors""" + self.authn_statem.authn_instant = "2007-08-31T01:05:02Z" + self.authn_statem.session_not_on_or_after = "2007-09-14T01:05:02Z" + self.authn_statem.session_index = "sessionindex" + self.authn_statem.authn_context = saml.AuthnContext() + self.authn_statem.authn_context.authn_context_class_ref = \ + saml.authn_context_class_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_CLASS_REF) + self.authn_statem.authn_context.authn_context_decl_ref = \ + saml.authn_context_decl_ref_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL_REF) + self.authn_statem.authn_context.authn_context_decl = \ + saml.authn_context_decl_from_string( + saml2_data.TEST_AUTHN_CONTEXT_DECL) + self.authn_statem.authn_context.authenticating_authority.append( + saml.authenticating_authority_from_string( + saml2_data.TEST_AUTHENTICATING_AUTHORITY)) + + new_as = saml.authn_statement_from_string(self.authn_statem.to_string()) + assert new_as.authn_instant == "2007-08-31T01:05:02Z" + assert new_as.session_index == "sessionindex" + assert new_as.session_not_on_or_after == "2007-09-14T01:05:02Z" + assert new_as.authn_context.authn_context_class_ref.text.strip() == \ + "http://www.example.com/authnContextClassRef" + assert new_as.authn_context.authn_context_decl_ref.text.strip() == \ + "http://www.example.com/authnContextDeclRef" + assert new_as.authn_context.authn_context_decl.text.strip() == \ + "http://www.example.com/authnContextDecl" + assert new_as.authn_context.authenticating_authority[0].text.strip() \ + == "http://www.example.com/authenticatingAuthority" + assert self.authn_statem.to_string() == new_as.to_string() + + def testUsingTestData(self): + """Test authn_statement_from_string() using test data""" + authn_statem = saml.authn_statement_from_string(saml2_data.TEST_AUTHN_STATEMENT) + assert authn_statem.authn_instant == "2007-08-31T01:05:02Z" + assert authn_statem.session_not_on_or_after == "2007-09-14T01:05:02Z" + assert authn_statem.authn_context.authn_context_class_ref.text.strip() == \ + saml.URN_PASSWORD + + +class TestAttributeValue: + + def setup_class(self): + self.attribute_value = saml.AttributeValue() + self.text = "value for test attribute" + + def testAccessors(self): + """Test for AttributeValue accessors""" + + self.attribute_value.text = self.text + new_attribute_value = saml.attribute_value_from_string( + self.attribute_value.to_string()) + assert new_attribute_value.text.strip() == self.text + + def testUsingTestData(self): + """Test attribute_value_from_string() using test data""" + + attribute_value = saml.attribute_value_from_string( + saml2_data.TEST_ATTRIBUTE_VALUE) + assert attribute_value.text.strip() == self.text + + +class TestAttribute: + + def setup_class(self): + self.attribute = saml.Attribute() + self.text = ["value of test attribute", + "value1 of test attribute", + "value2 of test attribute"] + + def testAccessors(self): + """Test for Attribute accessors""" + self.attribute.name = "testAttribute" + self.attribute.name_format = saml.NAME_FORMAT_URI + self.attribute.friendly_name = "test attribute" + self.attribute.attribute_value.append(saml.AttributeValue()) + self.attribute.attribute_value[0].text = self.text[0] + + new_attribute = saml.attribute_from_string(self.attribute.to_string()) + assert new_attribute.name == "testAttribute" + assert new_attribute.name_format == saml.NAME_FORMAT_URI + assert new_attribute.friendly_name == "test attribute" + assert new_attribute.attribute_value[0].text.strip() == self.text[0] + + def testUsingTestData(self): + """Test attribute_from_string() using test data""" + attribute = saml.attribute_from_string(saml2_data.TEST_ATTRIBUTE) + assert attribute.name == "testAttribute" + assert attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED + assert attribute.friendly_name == "test attribute" + assert attribute.attribute_value[0].text.strip() == self.text[1] + assert attribute.attribute_value[1].text.strip() == self.text[2] + # test again + attribute = saml.attribute_from_string(attribute.to_string()) + assert attribute.name == "testAttribute" + assert attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED + assert attribute.friendly_name == "test attribute" + assert attribute.attribute_value[0].text.strip() == self.text[1] + assert attribute.attribute_value[1].text.strip() == self.text[2] + + +class TestAttributeStatement: + + def setup_class(self): + self.attr_statem = saml.AttributeStatement() + self.text = ["value of test attribute", + "value1 of test attribute", + "value2 of test attribute", + "value1 of test attribute2", + "value2 of test attribute2",] + + def testAccessors(self): + """Test for Attribute accessors""" + self.attr_statem.attribute.append(saml.Attribute()) + self.attr_statem.attribute.append(saml.Attribute()) + self.attr_statem.attribute[0].name = "testAttribute" + self.attr_statem.attribute[0].name_format = saml.NAME_FORMAT_URI + self.attr_statem.attribute[0].friendly_name = "test attribute" + self.attr_statem.attribute[0].attribute_value.append(saml.AttributeValue()) + self.attr_statem.attribute[0].attribute_value[0].text = self.text[0] + + self.attr_statem.attribute[1].name = "testAttribute2" + self.attr_statem.attribute[1].name_format = saml.NAME_FORMAT_UNSPECIFIED + self.attr_statem.attribute[1].friendly_name = self.text[2] + self.attr_statem.attribute[1].attribute_value.append(saml.AttributeValue()) + self.attr_statem.attribute[1].attribute_value[0].text = self.text[2] + + new_as = saml.attribute_statement_from_string(self.attr_statem.to_string()) + assert new_as.attribute[0].name == "testAttribute" + assert new_as.attribute[0].name_format == saml.NAME_FORMAT_URI + assert new_as.attribute[0].friendly_name == "test attribute" + assert new_as.attribute[0].attribute_value[0].text.strip() == self.text[0] + assert new_as.attribute[1].name == "testAttribute2" + assert new_as.attribute[1].name_format == saml.NAME_FORMAT_UNSPECIFIED + assert new_as.attribute[1].friendly_name == "value2 of test attribute" + assert new_as.attribute[1].attribute_value[0].text.strip() == self.text[2] + + def testUsingTestData(self): + """Test attribute_statement_from_string() using test data""" + attr_statem = saml.attribute_statement_from_string(saml2_data.TEST_ATTRIBUTE_STATEMENT) + assert attr_statem.attribute[0].name == "testAttribute" + assert attr_statem.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED + assert attr_statem.attribute[0].friendly_name == "test attribute" + assert attr_statem.attribute[0].attribute_value[0].text.strip() == self.text[1] + assert attr_statem.attribute[0].attribute_value[1].text.strip() == self.text[2] + assert attr_statem.attribute[1].name == "http://www.example.com/testAttribute2" + assert attr_statem.attribute[1].name_format == saml.NAME_FORMAT_URI + assert attr_statem.attribute[1].friendly_name == "test attribute2" + assert attr_statem.attribute[1].attribute_value[0].text.strip() == self.text[3] + assert attr_statem.attribute[1].attribute_value[1].text.strip() == self.text[4] + + # test again + attr_statem2 = saml.attribute_statement_from_string(attr_statem.to_string()) + assert attr_statem2.attribute[0].name == "testAttribute" + assert attr_statem2.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED + assert attr_statem2.attribute[0].friendly_name == "test attribute" + assert attr_statem2.attribute[0].attribute_value[0].text.strip() == self.text[1] + assert attr_statem2.attribute[0].attribute_value[1].text.strip() == self.text[2] + assert attr_statem2.attribute[1].name == "http://www.example.com/testAttribute2" + assert attr_statem2.attribute[1].name_format == saml.NAME_FORMAT_URI + assert attr_statem2.attribute[1].friendly_name == "test attribute2" + assert attr_statem2.attribute[1].attribute_value[0].text.strip() == self.text[3] + assert attr_statem2.attribute[1].attribute_value[1].text.strip() == self.text[4] + + +class TestSubjectConfirmationData: + + def setup_class(self): + self.scd = saml.SubjectConfirmationData() + + def testAccessors(self): + """Test for SubjectConfirmationData accessors""" + + self.scd.not_before = "2007-08-31T01:05:02Z" + self.scd.not_on_or_after = "2007-09-14T01:05:02Z" + self.scd.recipient = "recipient" + self.scd.in_response_to = "responseID" + self.scd.address = "127.0.0.1" + new_scd = saml.subject_confirmation_data_from_string(self.scd.to_string()) + assert new_scd.not_before == "2007-08-31T01:05:02Z" + assert new_scd.not_on_or_after == "2007-09-14T01:05:02Z" + assert new_scd.recipient == "recipient" + assert new_scd.in_response_to == "responseID" + assert new_scd.address == "127.0.0.1" + + def testUsingTestData(self): + """Test subject_confirmation_data_from_string() using test data""" + + scd = saml.subject_confirmation_data_from_string( + saml2_data.TEST_SUBJECT_CONFIRMATION_DATA) + assert scd.not_before == "2007-08-31T01:05:02Z" + assert scd.not_on_or_after == "2007-09-14T01:05:02Z" + assert scd.recipient == "recipient" + assert scd.in_response_to == "responseID" + assert scd.address == "127.0.0.1" + + +class TestSubjectConfirmation: + + def setup_class(self): + self.sc = saml.SubjectConfirmation() + + def testAccessors(self): + """Test for SubjectConfirmation accessors""" + self.sc.name_id = saml.name_id_from_string(saml2_data.TEST_NAME_ID) + self.sc.method = saml.SUBJECT_CONFIRMATION_METHOD_BEARER + self.sc.subject_confirmation_data = saml.subject_confirmation_data_from_string( + saml2_data.TEST_SUBJECT_CONFIRMATION_DATA) + new_sc = saml.subject_confirmation_from_string(self.sc.to_string()) + assert new_sc.name_id.sp_provided_id == "sp provided id" + assert new_sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER + assert new_sc.subject_confirmation_data.not_before == \ + "2007-08-31T01:05:02Z" + assert new_sc.subject_confirmation_data.not_on_or_after == \ + "2007-09-14T01:05:02Z" + assert new_sc.subject_confirmation_data.recipient == "recipient" + assert new_sc.subject_confirmation_data.in_response_to == "responseID" + assert new_sc.subject_confirmation_data.address == "127.0.0.1" + + def testUsingTestData(self): + """Test subject_confirmation_from_string() using test data""" + + sc = saml.subject_confirmation_from_string( + saml2_data.TEST_SUBJECT_CONFIRMATION) + assert sc.name_id.sp_provided_id == "sp provided id" + assert sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER + assert sc.subject_confirmation_data.not_before == "2007-08-31T01:05:02Z" + assert sc.subject_confirmation_data.not_on_or_after == "2007-09-14T01:05:02Z" + assert sc.subject_confirmation_data.recipient == "recipient" + assert sc.subject_confirmation_data.in_response_to == "responseID" + assert sc.subject_confirmation_data.address == "127.0.0.1" + + +class TestSubject: + + def setup_class(self): + self.subject = saml.Subject() + + def testAccessors(self): + """Test for Subject accessors""" + self.subject.name_id = saml.name_id_from_string(saml2_data.TEST_NAME_ID) + self.subject.subject_confirmation.append( + saml.subject_confirmation_from_string( + saml2_data.TEST_SUBJECT_CONFIRMATION)) + new_subject = saml.subject_from_string(self.subject.to_string()) + assert new_subject.name_id.sp_provided_id == "sp provided id" + assert new_subject.name_id.text.strip() == "tmatsuo@example.com" + assert new_subject.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert isinstance(new_subject.subject_confirmation[0], + saml.SubjectConfirmation) + + def testUsingTestData(self): + """Test for subject_from_string() using test data.""" + + subject = saml.subject_from_string(saml2_data.TEST_SUBJECT) + assert subject.name_id.sp_provided_id == "sp provided id" + assert subject.name_id.text.strip() == "tmatsuo@example.com" + assert subject.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert isinstance(subject.subject_confirmation[0], + saml.SubjectConfirmation) + + +class TestCondition: + + def setup_class(self): + self.condition = saml.Condition() + self.name = "{%s}type" % saml.XSI_NAMESPACE + + def testAccessors(self): + """Test for Condition accessors.""" + self.condition.extension_attributes[self.name] = "test" + self.condition.extension_attributes['ExtendedAttribute'] = "value" + new_condition = saml.condition_from_string(self.condition.to_string()) + assert new_condition.extension_attributes[self.name] == "test" + assert new_condition.extension_attributes["ExtendedAttribute"] == "value" + + def testUsingTestData(self): + """Test for condition_from_string() using test data.""" + condition = saml.condition_from_string(saml2_data.TEST_CONDITION) + assert condition.extension_attributes[self.name] == "test" + assert condition.extension_attributes["ExtendedAttribute"] == "value" + + +class TestAudience: + + def setup_class(self): + self.audience = saml.Audience() + + def testAccessors(self): + """Test for Audience accessors""" + + self.audience.text = "http://www.example.com/Audience" + new_audience = saml.audience_from_string(self.audience.to_string()) + assert new_audience.text.strip() == "http://www.example.com/Audience" + + def testUsingTestData(self): + """Test audience_from_string using test data""" + + audience = saml.audience_from_string(saml2_data.TEST_AUDIENCE) + assert audience.text.strip() == "http://www.example.com/Audience" + + +class TestAudienceRestriction: + def setup_class(self): + self.audience_restriction = saml.AudienceRestriction() + + def testAccessors(self): + """Test for AudienceRestriction accessors""" + + self.audience_restriction.audience = \ + saml.audience_from_string(saml2_data.TEST_AUDIENCE) + new_audience = saml.audience_restriction_from_string( + self.audience_restriction.to_string()) + assert self.audience_restriction.audience.text.strip() == \ + "http://www.example.com/Audience" + + def testUsingTestData(self): + """Test audience_restriction_from_string using test data""" + + audience_restriction = saml.audience_restriction_from_string( + saml2_data.TEST_AUDIENCE_RESTRICTION) + assert audience_restriction.audience.text.strip() == \ + "http://www.example.com/Audience" + + +class TestOneTimeUse: + + def setup_class(self): + self.one_time_use = saml.OneTimeUse() + + def testAccessors(self): + """Test for OneTimeUse accessors""" + assert isinstance(self.one_time_use, saml.OneTimeUse) + assert isinstance(self.one_time_use, saml.Condition) + + def testUsingTestData(self): + """Test one_time_use_from_string() using test data""" + one_time_use = saml.one_time_use_from_string(saml2_data.TEST_ONE_TIME_USE) + assert isinstance(one_time_use, saml.OneTimeUse) + assert isinstance(one_time_use, saml.Condition) + + +class TestProxyRestriction: + + def setup_class(self): + self.proxy_restriction = saml.ProxyRestriction() + + def testAccessors(self): + """Test for ProxyRestriction accessors""" + + assert isinstance(self.proxy_restriction, saml.Condition) + self.proxy_restriction.count = "2" + self.proxy_restriction.audience.append(saml.audience_from_string( + saml2_data.TEST_AUDIENCE)) + new_proxy_restriction = saml.proxy_restriction_from_string( + self.proxy_restriction.to_string()) + assert new_proxy_restriction.count == "2" + assert new_proxy_restriction.audience[0].text.strip() == \ + "http://www.example.com/Audience" + + def testUsingTestData(self): + """Test proxy_restriction_from_string() using test data""" + + proxy_restriction = saml.proxy_restriction_from_string( + saml2_data.TEST_PROXY_RESTRICTION) + assert proxy_restriction.count == "2" + assert proxy_restriction.audience[0].text.strip() == \ + "http://www.example.com/Audience" + +class TestConditions: + + def setup_class(self): + self.conditions = saml.Conditions() + + def testAccessors(self): + """Test for Conditions accessors""" + self.conditions.not_before = "2007-08-31T01:05:02Z" + self.conditions.not_on_or_after = "2007-09-14T01:05:02Z" + self.conditions.condition.append(saml.Condition()) + self.conditions.audience_restriction.append(saml.AudienceRestriction()) + self.conditions.one_time_use.append(saml.OneTimeUse()) + self.conditions.proxy_restriction.append(saml.ProxyRestriction()) + new_conditions = saml.conditions_from_string(self.conditions.to_string()) + assert new_conditions.not_before == "2007-08-31T01:05:02Z" + assert new_conditions.not_on_or_after == "2007-09-14T01:05:02Z" + assert isinstance(new_conditions.condition[0], saml.Condition) + assert isinstance(new_conditions.audience_restriction[0], + saml.AudienceRestriction) + assert isinstance(new_conditions.one_time_use[0], + saml.OneTimeUse) + assert isinstance(new_conditions.proxy_restriction[0], + saml.ProxyRestriction) + + def testUsingTestData(self): + """Test conditions_from_string() using test data""" + new_conditions = saml.conditions_from_string(saml2_data.TEST_CONDITIONS) + assert new_conditions.not_before == "2007-08-31T01:05:02Z" + assert new_conditions.not_on_or_after == "2007-09-14T01:05:02Z" + assert isinstance(new_conditions.condition[0], saml.Condition) + assert isinstance(new_conditions.audience_restriction[0], + saml.AudienceRestriction) + assert isinstance(new_conditions.one_time_use[0], + saml.OneTimeUse) + assert isinstance(new_conditions.proxy_restriction[0], + saml.ProxyRestriction) + +class TestAssertionIDRef: + + def setup_class(self): + self.assertion_id_ref = saml.AssertionIDRef() + + def testAccessors(self): + """Test for AssertionIDRef accessors""" + self.assertion_id_ref.text = "zzlieajngjbkjggjldmgindkckkolcblndbghlhm" + new_assertion_id_ref = saml.assertion_id_ref_from_string( + self.assertion_id_ref.to_string()) + assert new_assertion_id_ref.text == \ + "zzlieajngjbkjggjldmgindkckkolcblndbghlhm" + + def testUsingTestData(self): + """Test assertion_id_ref_from_string() using test data""" + new_assertion_id_ref = saml.assertion_id_ref_from_string( + saml2_data.TEST_ASSERTION_ID_REF) + assert new_assertion_id_ref.text.strip() == \ + "zzlieajngjbkjggjldmgindkckkolcblndbghlhm" + + +class TestAssertionURIRef: + + def setup_class(self): + self.assertion_uri_ref = saml.AssertionURIRef() + + def testAccessors(self): + """Test for AssertionURIRef accessors""" + self.assertion_uri_ref.text = "http://www.example.com/AssertionURIRef" + new_assertion_uri_ref = saml.assertion_uri_ref_from_string( + self.assertion_uri_ref.to_string()) + assert new_assertion_uri_ref.text == \ + "http://www.example.com/AssertionURIRef" + + def testUsingTestData(self): + """Test assertion_uri_ref_from_string() using test data""" + new_assertion_uri_ref = saml.assertion_uri_ref_from_string( + saml2_data.TEST_ASSERTION_URI_REF) + assert new_assertion_uri_ref.text.strip() == \ + "http://www.example.com/AssertionURIRef" + + +class TestAction: + + def setup_class(self): + self.action = saml.Action() + + def testAccessors(self): + """Test for Action accessors""" + self.action.namespace = "http://www.example.com/Namespace" + new_action = saml.action_from_string(self.action.to_string()) + assert new_action.namespace == "http://www.example.com/Namespace" + + def testUsingTestData(self): + """Test action_from_string() using test data""" + new_action = saml.action_from_string(saml2_data.TEST_ACTION) + assert new_action.namespace == "http://www.example.com/Namespace" + + +class TestEvidence: + + def setup_class(self): + self.evidence = saml.Evidence() + + def testAccessors(self): + """Test for Evidence accessors""" + self.evidence.assertion_id_ref.append(saml.AssertionIDRef()) + self.evidence.assertion_uri_ref.append(saml.AssertionURIRef()) + self.evidence.assertion.append(saml.Assertion()) + self.evidence.encrypted_assertion.append(saml.EncryptedAssertion()) + new_evidence = saml.evidence_from_string(self.evidence.to_string()) + print new_evidence + assert self.evidence.to_string() == new_evidence.to_string() + assert isinstance(new_evidence.assertion_id_ref[0], + saml.AssertionIDRef) + assert isinstance(new_evidence.assertion_uri_ref[0], + saml.AssertionURIRef) + assert len(new_evidence.assertion) == 1 + assert isinstance(new_evidence.assertion[0], saml.Assertion) + assert len(new_evidence.encrypted_assertion) == 1 + assert isinstance(new_evidence.encrypted_assertion[0], + saml.EncryptedAssertion) + + def testUsingTestData(self): + """Test evidence_from_string() using test data""" + # TODO: + pass + + +class TestAuthzDecisionStatement: + + def setup_class(self): + self.authz_decision_statement = saml.AuthzDecisionStatement() + + def testAccessors(self): + """Test for AuthzDecisionStatement accessors""" + self.authz_decision_statement.resource = "http://www.example.com/Resource" + self.authz_decision_statement.decision = saml.DECISION_TYPE_PERMIT + self.authz_decision_statement.action.append(saml.Action()) + self.authz_decision_statement.evidence.append(saml.Evidence()) + new_authz_decision_statement = saml.authz_decision_statement_from_string( + self.authz_decision_statement.to_string()) + assert self.authz_decision_statement.to_string() == \ + new_authz_decision_statement.to_string() + assert new_authz_decision_statement.resource == \ + "http://www.example.com/Resource" + assert new_authz_decision_statement.decision == \ + saml.DECISION_TYPE_PERMIT + assert isinstance(new_authz_decision_statement.action[0], + saml.Action) + assert isinstance(new_authz_decision_statement.evidence[0], + saml.Evidence) + + + def testUsingTestData(self): + """Test authz_decision_statement_from_string() using test data""" + # TODO: + pass + +class TestAdvice: + + def setup_class(self): + self.advice = saml.Advice() + + def testAccessors(self): + """Test for Advice accessors""" + self.advice.assertion_id_ref.append(saml.AssertionIDRef()) + self.advice.assertion_uri_ref.append(saml.AssertionURIRef()) + self.advice.assertion.append(saml.Assertion()) + self.advice.encrypted_assertion.append(saml.EncryptedAssertion()) + new_advice = saml.advice_from_string(self.advice.to_string()) + assert self.advice.to_string() == new_advice.to_string() + assert isinstance(new_advice.assertion_id_ref[0], + saml.AssertionIDRef) + assert isinstance(new_advice.assertion_uri_ref[0], + saml.AssertionURIRef) + assert isinstance(new_advice.assertion[0], saml.Assertion) + assert isinstance(new_advice.encrypted_assertion[0], + saml.EncryptedAssertion) + + def testUsingTestData(self): + """Test advice_from_string() using test data""" + # TODO: + pass + + +class TestAssertion: + + def setup_class(self): + self.assertion = saml.Assertion() + + def testAccessors(self): + """Test for Assertion accessors""" + self.assertion.id = "assertion id" + self.assertion.version = saml2.VERSION + self.assertion.issue_instant = "2007-08-31T01:05:02Z" + self.assertion.issuer = saml.issuer_from_string(saml2_data.TEST_ISSUER) + self.assertion.signature = ds.signature_from_string( + ds_data.TEST_SIGNATURE) + self.assertion.subject = saml.subject_from_string(saml2_data.TEST_SUBJECT) + self.assertion.conditions = saml.conditions_from_string( + saml2_data.TEST_CONDITIONS) + self.assertion.advice = saml.Advice() + self.assertion.statement.append(saml.Statement()) + self.assertion.authn_statement.append(saml.authn_statement_from_string( + saml2_data.TEST_AUTHN_STATEMENT)) + self.assertion.authz_decision_statement.append( + saml.AuthzDecisionStatement()) + self.assertion.attribute_statement.append( + saml.attribute_statement_from_string( + saml2_data.TEST_ATTRIBUTE_STATEMENT)) + + new_assertion = saml.assertion_from_string(self.assertion.to_string()) + assert new_assertion.id == "assertion id" + assert new_assertion.version == saml2.VERSION + assert new_assertion.issue_instant == "2007-08-31T01:05:02Z" + assert isinstance(new_assertion.issuer, saml.Issuer) + assert isinstance(new_assertion.signature, ds.Signature) + assert isinstance(new_assertion.subject, saml.Subject) + assert isinstance(new_assertion.conditions, saml.Conditions) + assert isinstance(new_assertion.advice, saml.Advice) + assert isinstance(new_assertion.statement[0], saml.Statement) + assert isinstance(new_assertion.authn_statement[0], + saml.AuthnStatement) + assert isinstance(new_assertion.authz_decision_statement[0], + saml.AuthzDecisionStatement) + assert isinstance(new_assertion.attribute_statement[0], + saml.AttributeStatement) + + + def testUsingTestData(self): + """Test assertion_from_string() using test data""" + # TODO + pass diff --git a/tests/test_1_samlp.py b/tests/test_1_samlp.py new file mode 100644 index 0000000..8e739d6 --- /dev/null +++ b/tests/test_1_samlp.py @@ -0,0 +1,535 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009 Umeå University. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for saml2.samlp""" + +__author__ = 'roland.hedberg@adm.umu.se (Roland Hedberg)' + +import unittest +try: + from xml.etree import ElementTree +except ImportError: + from elementtree import ElementTree +import saml2 +from saml2 import saml, samlp +import saml2_data, ds_data, samlp_data +import xmldsig as ds + + +class TestAbstractRequest: + + def setup_class(self): + self.ar = samlp.AbstractRequest() + + def testAccessors(self): + """Test for AbstractRequest accessors""" + self.ar.id = "request id" + self.ar.version = saml2.VERSION + self.ar.issue_instant = "2007-09-14T01:05:02Z" + self.ar.destination = "http://www.example.com/Destination" + self.ar.consent = saml.CONSENT_UNSPECIFIED + self.ar.issuer = saml.Issuer() + self.ar.signature = ds.get_empty_signature() + self.ar.extensions = samlp.Extensions() + + new_ar = samlp.abstract_request_from_string(self.ar.to_string()) + assert new_ar.id == "request id" + assert new_ar.version == saml2.VERSION + assert new_ar.issue_instant == "2007-09-14T01:05:02Z" + assert new_ar.destination == "http://www.example.com/Destination" + assert new_ar.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_ar.issuer, saml.Issuer) + assert isinstance(new_ar.signature, ds.Signature) + assert isinstance(new_ar.extensions, samlp.Extensions) + + def testUsingTestData(self): + """Test for abstract_request_from_string() using test data""" + # TODO: + pass + +class TestStatusDetail: + + def setup_class(self): + self.status_detail = samlp.StatusDetail() + + def testAccessors(self): + """Test for StatusDetail accessors""" + # TODO: + pass + + +class TestStatusMessage: + + def setup_class(self): + self.status_message = samlp.StatusMessage() + + def testAccessors(self): + """Test for StatusMessage accessors""" + # TODO: + pass + + +class TestStatusCode: + + def setup_class(self): + self.status_code = samlp.StatusCode() + + def testAccessors(self): + """Test for StatusCode accessors""" + self.status_code.value = samlp.STATUS_RESPONDER + self.status_code.status_code = samlp.StatusCode( + value=samlp.STATUS_REQUEST_DENIED) + print self.status_code.__dict__ + new_status_code = samlp.status_code_from_string(self.status_code.to_string()) + assert new_status_code.value == samlp.STATUS_RESPONDER + assert new_status_code.status_code.value == \ + samlp.STATUS_REQUEST_DENIED + + def testUsingTestData(self): + """Test for status_code_from_string() using test data""" + new_status_code = samlp.status_code_from_string( + samlp_data.TEST_STATUS_CODE) + assert new_status_code.value == samlp.STATUS_RESPONDER + assert new_status_code.status_code.value == \ + samlp.STATUS_REQUEST_DENIED + + +class TestStatus: + + def setup_class(self): + self.status = samlp.Status() + + def testAccessors(self): + """Test for Status accessors""" + self.status.status_code = samlp.StatusCode() + self.status.status_message = samlp.StatusMessage() + self.status.status_detail = samlp.StatusDetail() + new_status = samlp.status_from_string(self.status.to_string()) + assert isinstance(new_status.status_code, samlp.StatusCode) + assert isinstance(new_status.status_message, samlp.StatusMessage) + assert isinstance(new_status.status_detail, samlp.StatusDetail) + + def testUsingTestData(self): + """Test for status_from_string using test data""" + new_status = samlp.status_from_string(samlp_data.TEST_STATUS) + assert isinstance(new_status.status_code, samlp.StatusCode) + assert isinstance(new_status.status_code.status_code, + samlp.StatusCode) + assert isinstance(new_status.status_message, samlp.StatusMessage) + assert isinstance(new_status.status_detail, samlp.StatusDetail) + +class TestStatusResponse: + + def setup_class(self): + self.sr = samlp.StatusResponse() + + def testAccessors(self): + """Test for StatusResponse accessors""" + self.sr.id = "response id" + self.sr.in_response_to = "request id" + self.sr.version = saml2.VERSION + self.sr.issue_instant = "2007-09-14T01:05:02Z" + self.sr.destination = "http://www.example.com/Destination" + self.sr.consent = saml.CONSENT_UNSPECIFIED + self.sr.issuer = saml.Issuer() + self.sr.signature = ds.get_empty_signature() + self.sr.extensions = samlp.Extensions() + self.sr.status = samlp.Status() + + new_sr = samlp.status_response_from_string(self.sr.to_string()) + assert new_sr.id == "response id" + assert new_sr.in_response_to == "request id" + assert new_sr.version == saml2.VERSION + assert new_sr.issue_instant == "2007-09-14T01:05:02Z" + assert new_sr.destination == "http://www.example.com/Destination" + assert new_sr.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_sr.issuer, saml.Issuer) + assert isinstance(new_sr.signature, ds.Signature) + assert isinstance(new_sr.extensions, samlp.Extensions) + assert isinstance(new_sr.status, samlp.Status) + + def testUsingTestData(self): + """Test for status_response_from_string() using test data""" + # TODO: + pass + + +class TestResponse: + + def setup_class(self): + self.response = samlp.Response() + + def testAccessors(self): + """Test for Response accessors""" + self.response.id = "response id" + self.response.in_response_to = "request id" + self.response.version = saml2.VERSION + self.response.issue_instant = "2007-09-14T01:05:02Z" + self.response.destination = "http://www.example.com/Destination" + self.response.consent = saml.CONSENT_UNSPECIFIED + self.response.issuer = saml.Issuer() + self.response.signature = ds.get_empty_signature() + self.response.extensions = samlp.Extensions() + self.response.status = samlp.Status() + self.response.assertion.append(saml.Assertion()) + self.response.encrypted_assertion.append(saml.EncryptedAssertion()) + + new_response = samlp.response_from_string(self.response.to_string()) + assert new_response.id == "response id" + assert new_response.in_response_to == "request id" + assert new_response.version == saml2.VERSION + assert new_response.issue_instant == "2007-09-14T01:05:02Z" + assert new_response.destination == "http://www.example.com/Destination" + assert new_response.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_response.issuer, saml.Issuer) + assert isinstance(new_response.signature, ds.Signature) + assert isinstance(new_response.extensions, samlp.Extensions) + assert isinstance(new_response.status, samlp.Status) + + assert isinstance(new_response.assertion[0], saml.Assertion) + assert isinstance(new_response.encrypted_assertion[0], + saml.EncryptedAssertion) + + def testUsingTestData(self): + """Test for response_from_string() using test data""" + # TODO: + pass + +class TestNameIDPolicy: + + def setup_class(self): + self.name_id_policy = samlp.NameIDPolicy() + + def testAccessors(self): + """Test for NameIDPolicy accessors""" + self.name_id_policy.format = saml.NAMEID_FORMAT_EMAILADDRESS + self.name_id_policy.sp_name_qualifier = saml.NAMEID_FORMAT_PERSISTENT + self.name_id_policy.allow_create = 'false' + + new_name_id_policy = samlp.name_id_policy_from_string( + self.name_id_policy.to_string()) + + assert new_name_id_policy.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert new_name_id_policy.sp_name_qualifier == \ + saml.NAMEID_FORMAT_PERSISTENT + assert new_name_id_policy.allow_create == 'false' + + def testUsingTestData(self): + """Test for name_id_policy_from_string() using test data""" + new_name_id_policy = samlp.name_id_policy_from_string( + samlp_data.TEST_NAME_ID_POLICY) + + assert new_name_id_policy.format == saml.NAMEID_FORMAT_EMAILADDRESS + assert new_name_id_policy.sp_name_qualifier == \ + saml.NAMEID_FORMAT_PERSISTENT + assert new_name_id_policy.allow_create == 'false' + + +class TestIDPEntry: + + def setup_class(self): + self.idp_entry = samlp.IDPEntry() + + def testAccessors(self): + """Test for IDPEntry accessors""" + self.idp_entry.provider_id = "http://www.example.com/provider" + self.idp_entry.name = "the provider" + self.idp_entry.loc = "http://www.example.com/Loc" + + new_idp_entry = samlp.idp_entry_from_string(self.idp_entry.to_string()) + assert new_idp_entry.provider_id == "http://www.example.com/provider" + assert new_idp_entry.name == "the provider" + assert new_idp_entry.loc == "http://www.example.com/Loc" + + def testUsingTestData(self): + """Test for idp_entry_from_string() using test data""" + new_idp_entry = samlp.idp_entry_from_string(samlp_data.TEST_IDP_ENTRY) + assert new_idp_entry.provider_id == "http://www.example.com/provider" + assert new_idp_entry.name == "the provider" + assert new_idp_entry.loc == "http://www.example.com/Loc" + + +class TestIDPList: + + def setup_class(self): + self.idp_list = samlp.IDPList() + + def testAccessors(self): + """Test for IDPList accessors""" + self.idp_list.idp_entry.append(samlp.idp_entry_from_string( + samlp_data.TEST_IDP_ENTRY)) + self.idp_list.get_complete = samlp.GetComplete( + text="http://www.example.com/GetComplete") + new_idp_list = samlp.idp_list_from_string(self.idp_list.to_string()) + assert isinstance(new_idp_list.idp_entry[0], samlp.IDPEntry) + assert new_idp_list.get_complete.text.strip() == \ + "http://www.example.com/GetComplete" + + def testUsingTestData(self): + """Test for idp_list_from_string() using test data""" + new_idp_list = samlp.idp_list_from_string(samlp_data.TEST_IDP_LIST) + assert isinstance(new_idp_list.idp_entry[0], samlp.IDPEntry) + assert new_idp_list.get_complete.text.strip() == \ + "http://www.example.com/GetComplete" + + +class TestScoping: + + def setup_class(self): + self.scoping = samlp.Scoping() + + def testAccessors(self): + """Test for Scoping accessors""" + + self.scoping.proxy_count = "1" + self.scoping.idp_list = samlp.IDPList() + self.scoping.requester_id.append(samlp.RequesterID()) + + new_scoping = samlp.scoping_from_string(self.scoping.to_string()) + + assert new_scoping.proxy_count == "1" + assert isinstance(new_scoping.idp_list, samlp.IDPList) + assert isinstance(new_scoping.requester_id[0], samlp.RequesterID) + + def testUsingTestData(self): + """Test for scoping_from_string() using test data""" + new_scoping = samlp.scoping_from_string(samlp_data.TEST_SCOPING) + + assert new_scoping.proxy_count == "1" + assert isinstance(new_scoping.idp_list, samlp.IDPList) + assert isinstance(new_scoping.requester_id[0], samlp.RequesterID) + + +class TestRequestedAuthnContext: + + def setup_class(self): + self.context = samlp.RequestedAuthnContext() + + def testAccessors(self): + """Test for RequestedAuthnContext accessors""" + + self.context.authn_context_class_ref.append(saml.AuthnContextClassRef()) + self.context.authn_context_decl_ref.append(saml.AuthnContextDeclRef()) + self.context.comparison = "exact" + + new_context = samlp.requested_authn_context_from_string( + self.context.to_string()) + + assert isinstance(new_context.authn_context_class_ref[0], + saml.AuthnContextClassRef) + assert isinstance(new_context.authn_context_decl_ref[0], + saml.AuthnContextDeclRef) + assert new_context.comparison == "exact" + + def testUsingTestData(self): + """Test for requested_authn_context_from_string() using test data""" + new_context = samlp.requested_authn_context_from_string( + samlp_data.TEST_REQUESTED_AUTHN_CONTEXT) + + assert isinstance(new_context.authn_context_class_ref[0], + saml.AuthnContextClassRef) + assert isinstance(new_context.authn_context_decl_ref[0], + saml.AuthnContextDeclRef) + assert new_context.comparison == "exact" + + +class TestAuthnRequest: + + def setup_class(self): + self.ar = samlp.AuthnRequest() + + def testAccessors(self): + """Test for AuthnRequest accessors""" + self.ar.id = "request id" + self.ar.version = saml2.VERSION + self.ar.issue_instant = "2007-09-14T01:05:02Z" + self.ar.destination = "http://www.example.com/Destination" + self.ar.consent = saml.CONSENT_UNSPECIFIED + self.ar.issuer = saml.Issuer() + self.ar.signature = ds.get_empty_signature() + self.ar.extensions = samlp.Extensions() + + self.ar.subject = saml.Subject() + self.ar.name_id_policy = samlp.NameIDPolicy() + self.ar.conditions = saml.Conditions() + self.ar.requested_authn_context = samlp.RequestedAuthnContext() + self.ar.scoping = samlp.Scoping() + self.ar.force_authn = 'true' + self.ar.is_passive = 'true' + self.ar.assertion_consumer_service_index = "1" + self.ar.assertion_consumer_service_url = "http://www.example.com/acs" + self.ar.protocol_binding = saml2.BINDING_HTTP_POST + self.ar.assertion_consuming_service_index = "2" + self.ar.provider_name = "provider name" + + new_ar = samlp.authn_request_from_string(self.ar.to_string()) + assert new_ar.id == "request id" + assert new_ar.version == saml2.VERSION + assert new_ar.issue_instant == "2007-09-14T01:05:02Z" + assert new_ar.destination == "http://www.example.com/Destination" + assert new_ar.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_ar.issuer, saml.Issuer) + assert isinstance(new_ar.signature, ds.Signature) + assert isinstance(new_ar.extensions, samlp.Extensions) + + assert isinstance(new_ar.subject, saml.Subject) + assert isinstance(new_ar.name_id_policy, samlp.NameIDPolicy) + assert isinstance(new_ar.conditions, saml.Conditions) + assert isinstance(new_ar.requested_authn_context, + samlp.RequestedAuthnContext) + assert isinstance(new_ar.scoping, samlp.Scoping) + assert new_ar.force_authn == 'true' + assert new_ar.is_passive == 'true' + assert new_ar.assertion_consumer_service_index == '1' + assert new_ar.assertion_consumer_service_url == \ + 'http://www.example.com/acs' + assert new_ar.protocol_binding == saml2.BINDING_HTTP_POST + assert new_ar.assertion_consuming_service_index == '2' + assert new_ar.provider_name == "provider name" + + def testUsingTestData(self): + """Test for authn_request_from_string() using test data""" + new_ar = samlp.authn_request_from_string(samlp_data.TEST_AUTHN_REQUEST) + assert new_ar.id == "request id" + assert new_ar.version == saml2.VERSION + assert new_ar.issue_instant == "2007-09-14T01:05:02Z" + assert new_ar.destination == "http://www.example.com/Destination" + assert new_ar.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_ar.issuer, saml.Issuer) + assert isinstance(new_ar.signature, ds.Signature) + assert isinstance(new_ar.extensions, samlp.Extensions) + + assert isinstance(new_ar.subject, saml.Subject) + assert isinstance(new_ar.name_id_policy, samlp.NameIDPolicy) + assert isinstance(new_ar.conditions, saml.Conditions) + assert isinstance(new_ar.requested_authn_context, + samlp.RequestedAuthnContext) + assert isinstance(new_ar.scoping, samlp.Scoping) + assert new_ar.force_authn == 'true' + assert new_ar.is_passive == 'true' + assert new_ar.assertion_consumer_service_index == '1' + assert new_ar.assertion_consumer_service_url == \ + 'http://www.example.com/acs' + assert new_ar.protocol_binding == saml2.BINDING_HTTP_POST + assert new_ar.assertion_consuming_service_index == '2' + assert new_ar.provider_name == "provider name" + + +class TestLogoutRequest: + + def setup_class(self): + self.lr = samlp.LogoutRequest() + + def testAccessors(self): + """Test for LogoutRequest accessors""" + self.lr.id = "request id" + self.lr.version = saml2.VERSION + self.lr.issue_instant = "2007-09-14T01:05:02Z" + self.lr.destination = "http://www.example.com/Destination" + self.lr.consent = saml.CONSENT_UNSPECIFIED + self.lr.issuer = saml.Issuer() + self.lr.signature = ds.get_empty_signature() + self.lr.extensions = samlp.Extensions() + + self.lr.not_on_or_after = "2007-10-14T01:05:02Z" + self.lr.reason = "http://www.example.com/Reason" + self.lr.base_id = saml.BaseID() + self.lr.name_id = saml.NameID() + self.lr.encrypted_id = saml.EncryptedID() + self.lr.session_index = samlp.SessionIndex() + + new_lr = samlp.logout_request_from_string(self.lr.to_string()) + assert new_lr.id == "request id" + assert new_lr.version == saml2.VERSION + assert new_lr.issue_instant == "2007-09-14T01:05:02Z" + assert new_lr.destination == "http://www.example.com/Destination" + assert new_lr.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_lr.issuer, saml.Issuer) + assert isinstance(new_lr.signature, ds.Signature) + assert isinstance(new_lr.extensions, samlp.Extensions) + assert new_lr.not_on_or_after == "2007-10-14T01:05:02Z" + assert new_lr.reason == "http://www.example.com/Reason" + assert isinstance(new_lr.base_id, saml.BaseID) + assert isinstance(new_lr.name_id, saml.NameID) + assert isinstance(new_lr.encrypted_id, saml.EncryptedID) + assert isinstance(new_lr.session_index, samlp.SessionIndex) + + def testUsingTestData(self): + """Test for logout_request_from_string() using test data""" + new_lr = samlp.logout_request_from_string(samlp_data.TEST_LOGOUT_REQUEST) + assert new_lr.id == "request id" + assert new_lr.version == saml2.VERSION + assert new_lr.issue_instant == "2007-09-14T01:05:02Z" + assert new_lr.destination == "http://www.example.com/Destination" + assert new_lr.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_lr.issuer, saml.Issuer) + assert isinstance(new_lr.signature, ds.Signature) + assert isinstance(new_lr.extensions, samlp.Extensions) + assert new_lr.not_on_or_after == "2007-10-14T01:05:02Z" + assert new_lr.reason == "http://www.example.com/Reason" + assert isinstance(new_lr.base_id, saml.BaseID) + assert isinstance(new_lr.name_id, saml.NameID) + assert isinstance(new_lr.encrypted_id, saml.EncryptedID) + assert isinstance(new_lr.session_index, samlp.SessionIndex) + assert new_lr.session_index.text.strip() == "session index" + + +class TestLogoutResponse: + + def setup_class(self): + self.lr = samlp.LogoutResponse() + + def testAccessors(self): + """Test for LogoutResponse accessors""" + self.lr.id = "response id" + self.lr.in_response_to = "request id" + self.lr.version = saml2.VERSION + self.lr.issue_instant = "2007-09-14T01:05:02Z" + self.lr.destination = "http://www.example.com/Destination" + self.lr.consent = saml.CONSENT_UNSPECIFIED + self.lr.issuer = saml.Issuer() + self.lr.signature = ds.get_empty_signature() + self.lr.extensions = samlp.Extensions() + self.lr.status = samlp.Status() + + new_lr = samlp.logout_response_from_string(self.lr.to_string()) + assert new_lr.id == "response id" + assert new_lr.in_response_to == "request id" + assert new_lr.version == saml2.VERSION + assert new_lr.issue_instant == "2007-09-14T01:05:02Z" + assert new_lr.destination == "http://www.example.com/Destination" + assert new_lr.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_lr.issuer, saml.Issuer) + assert isinstance(new_lr.signature, ds.Signature) + assert isinstance(new_lr.extensions, samlp.Extensions) + assert isinstance(new_lr.status, samlp.Status) + + def testUsingTestData(self): + """Test for logout_response_from_string() using test data""" + new_lr = samlp.logout_response_from_string( + samlp_data.TEST_LOGOUT_RESPONSE) + assert new_lr.id == "response id" + assert new_lr.in_response_to == "request id" + assert new_lr.version == saml2.VERSION + assert new_lr.issue_instant == "2007-09-14T01:05:02Z" + assert new_lr.destination == "http://www.example.com/Destination" + assert new_lr.consent == saml.CONSENT_UNSPECIFIED + assert isinstance(new_lr.issuer, saml.Issuer) + assert isinstance(new_lr.signature, ds.Signature) + assert isinstance(new_lr.extensions, samlp.Extensions) + assert isinstance(new_lr.status, samlp.Status) + diff --git a/tests/test_2_md.py b/tests/test_2_md.py new file mode 100644 index 0000000..69780b7 --- /dev/null +++ b/tests/test_2_md.py @@ -0,0 +1,1157 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009 Umeå University. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for saml2.md""" + +__author__ = 'roland.hedberg@umu.se (Roland Hedberg)' + +import unittest +try: + from xml.etree import ElementTree +except ImportError: + from elementtree import ElementTree +import saml2 +from saml2 import saml, samlp, md +import md_data, ds_data +import xmldsig as ds + +class TestEndpoint: + + def setup_class(self): + self.endpoint = md.Endpoint() + + def testAccessors(self): + """Test for Endpoint accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + print self.endpoint.__class__.c_attributes.items() + new_endpoint = md.endpoint_from_string(self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for endpoint_from_string() using test data.""" + new_endpoint = md.endpoint_from_string(md_data.TEST_ENDPOINT) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + +class TestIndexedEndpoint: + + def setup_class(self): + self.i_e = md.IndexedEndpoint() + + def testAccessors(self): + """Test for IndexedEndpoint accessors""" + self.i_e.binding = saml2.BINDING_HTTP_POST + self.i_e.location = "http://www.example.com/endpoint" + self.i_e.response_location = "http://www.example.com/response" + self.i_e.index = "1" + self.i_e.is_default = "false" + new_i_e = md.indexed_endpoint_from_string(self.i_e.to_string()) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + def testUsingTestData(self): + """Test for indexed_endpoint_from_string() using test data.""" + new_i_e = md.indexed_endpoint_from_string(md_data.TEST_INDEXED_ENDPOINT) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + +class TestExtensions: + + def setup_class(self): + self.extensions = md.Extensions() + + def testAccessors(self): + """Test for Extensions accessors""" + self.extensions.extension_elements.append( + saml2.extension_element_from_string( + """ + fuga + """)) + new_extensions = md.extensions_from_string(self.extensions.to_string()) + assert new_extensions.extension_elements[0].tag == "hoge" + assert new_extensions.extension_elements[0].text.strip() == "fuga" + + +class TestOrganizationName: + + def setup_class(self): + self.organization_name = md.OrganizationName() + + def testAccessors(self): + """Test for OrganizationName accessors""" + self.organization_name.lang = "en" + self.organization_name.text = "SIOS Technology, Inc." + new_organization_name = md.organization_name_from_string( + self.organization_name.to_string()) + assert new_organization_name.lang == "en" + assert new_organization_name.text.strip() == "SIOS Technology, Inc." + + def testUsingTestData(self): + """Test for organization_name_from_string() using test data.""" + new_organization_name = md.organization_name_from_string( + md_data.TEST_ORGANIZATION_NAME) + assert new_organization_name.lang == "en" + assert new_organization_name.text.strip() == "SIOS Technology, Inc." + + +class TestOrganizationDisplayName: + + def setup_class(self): + self.od_name = md.OrganizationDisplayName() + + def testAccessors(self): + """Test for OrganizationDisplayName accessors""" + self.od_name.lang = "en" + self.od_name.text = "SIOS" + new_od_name = md.organization_display_name_from_string( + self.od_name.to_string()) + assert new_od_name.lang == "en" + assert new_od_name.text.strip() == "SIOS" + + def testUsingTestData(self): + """Test for organization_display_name_from_string() using test data.""" + new_od_name = md.organization_display_name_from_string( + md_data.TEST_ORGANIZATION_DISPLAY_NAME) + assert new_od_name.lang == "en" + assert new_od_name.text.strip() == "SIOS" + + +class TestOrganizationURL: + + def setup_class(self): + self.organization_url = md.OrganizationURL() + + def testAccessors(self): + """Test for OrganizationURL accessors""" + self.organization_url.lang = "ja" + self.organization_url.text = "http://www.example.com/" + new_organization_url = md.organization_url_from_string( + self.organization_url.to_string()) + assert new_organization_url.lang == "ja" + assert new_organization_url.text.strip() == "http://www.example.com/" + + def testUsingTestData(self): + """Test for organization_url_from_string() using test data.""" + new_organization_url = md.organization_url_from_string( + md_data.TEST_ORGANIZATION_URL) + assert new_organization_url.lang == "ja" + assert new_organization_url.text.strip() == "http://www.example.com/" + + +class TestOrganization: + + def setup_class(self): + self.organization = md.Organization() + + def testAccessors(self): + """Test for Organization accessors""" + self.organization.extensions = md.Extensions() + self.organization.organization_name.append( + md.organization_name_from_string(md_data.TEST_ORGANIZATION_NAME)) + self.organization.organization_display_name.append( + md.organization_display_name_from_string( + md_data.TEST_ORGANIZATION_DISPLAY_NAME)) + self.organization.organization_url.append( + md.organization_url_from_string(md_data.TEST_ORGANIZATION_URL)) + new_organization = md.organization_from_string(self.organization.to_string()) + assert isinstance(new_organization.extensions, md.Extensions) + assert isinstance(new_organization.organization_name[0], + md.OrganizationName) + assert isinstance(new_organization.organization_display_name[0], + md.OrganizationDisplayName) + assert isinstance(new_organization.organization_url[0], + md.OrganizationURL) + assert new_organization.organization_name[0].text.strip() == "SIOS Technology, Inc." + assert new_organization.organization_name[0].lang == "en" + assert new_organization.organization_display_name[0].text.strip() == "SIOS" + assert new_organization.organization_display_name[0].lang == "en" + assert new_organization.organization_url[0].text.strip() == "http://www.example.com/" + assert new_organization.organization_url[0].lang == "ja" + + + def testUsingTestData(self): + """Test for organization_from_string() using test data.""" + new_organization = md.organization_from_string( + md_data.TEST_ORGANIZATION) + assert isinstance(new_organization.extensions, md.Extensions) + assert isinstance(new_organization.organization_name[0], + md.OrganizationName) + assert isinstance(new_organization.organization_display_name[0], + md.OrganizationDisplayName) + assert isinstance(new_organization.organization_url[0], + md.OrganizationURL) + assert new_organization.organization_name[0].text.strip() == "SIOS Technology, Inc." + assert new_organization.organization_name[0].lang == "en" + assert new_organization.organization_display_name[0].text.strip() == "SIOS" + assert new_organization.organization_display_name[0].lang == "en" + assert new_organization.organization_url[0].text.strip() == "http://www.example.com/" + assert new_organization.organization_url[0].lang == "ja" + + +class TestContactPerson: + + def setup_class(self): + self.contact_person = md.ContactPerson() + + def testAccessors(self): + """Test for ContactPerson accessors""" + self.contact_person.contact_type = "technical" + self.contact_person.extensions = md.Extensions() + self.contact_person.company = md.Company(text="SIOS Technology, Inc.") + self.contact_person.given_name = md.GivenName(text="Takashi") + self.contact_person.sur_name = md.SurName(text="Matsuo") + self.contact_person.email_address.append( + md.EmailAddress(text="tmatsuo@example.com")) + self.contact_person.email_address.append( + md.EmailAddress(text="tmatsuo@shehas.net")) + self.contact_person.telephone_number.append( + md.TelephoneNumber(text="00-0000-0000")) + new_contact_person = md.contact_person_from_string( + self.contact_person.to_string()) + assert new_contact_person.contact_type == "technical" + assert isinstance(new_contact_person.extensions, md.Extensions) + assert new_contact_person.company.text.strip() == "SIOS Technology, Inc." + assert new_contact_person.given_name.text.strip() == "Takashi" + assert new_contact_person.sur_name.text.strip() == "Matsuo" + assert new_contact_person.email_address[0].text.strip() == "tmatsuo@example.com" + assert new_contact_person.email_address[1].text.strip() == "tmatsuo@shehas.net" + assert new_contact_person.telephone_number[0].text.strip() == "00-0000-0000" + + def testUsingTestData(self): + """Test for contact_person_from_string() using test data.""" + new_contact_person = md.contact_person_from_string( + md_data.TEST_CONTACT_PERSON) + assert new_contact_person.contact_type == "technical" + assert isinstance(new_contact_person.extensions, md.Extensions) + assert new_contact_person.company.text.strip() == "SIOS Technology, Inc." + assert new_contact_person.given_name.text.strip() == "Takashi" + assert new_contact_person.sur_name.text.strip() == "Matsuo" + assert new_contact_person.email_address[0].text.strip() == "tmatsuo@example.com" + assert new_contact_person.email_address[1].text.strip() == "tmatsuo@shehas.net" + assert new_contact_person.telephone_number[0].text.strip() == "00-0000-0000" + +class TestAdditionalMetadataLocation: + + def setup_class(self): + self.additional_metadata_location = md.AdditionalMetadataLocation() + + def testAccessors(self): + """Test for AdditionalMetadataLocation accessors""" + self.additional_metadata_location.namespace = ( + "http://www.example.com/namespace") + self.additional_metadata_location.text = ( + "http://www.example.com/AdditionalMetadataLocation") + new_additional_metadata_location = md.additional_metadata_location_from_string( + self.additional_metadata_location.to_string()) + assert new_additional_metadata_location.namespace == "http://www.example.com/namespace" + assert new_additional_metadata_location.text.strip() == "http://www.example.com/AdditionalMetadataLocation" + + def testUsingTestData(self): + """Test for additional_metadata_location_from_string() using test data.""" + new_additional_metadata_location = md.additional_metadata_location_from_string( + md_data.TEST_ADDITIONAL_METADATA_LOCATION) + assert new_additional_metadata_location.namespace == "http://www.example.com/namespace" + assert new_additional_metadata_location.text.strip() == "http://www.example.com/AdditionalMetadataLocation" + +class TestKeySize: + + def setup_class(self): + self.key_size = md.KeySize() + + def testAccessors(self): + """Test for KeySize accessors""" + self.key_size.text = "128" + new_key_size = md.key_size_from_string(self.key_size.to_string()) + assert new_key_size.text.strip() == "128" + + def testUsingTestData(self): + """Test for key_size_from_string() using test data.""" + new_key_size = md.key_size_from_string(md_data.TEST_KEY_SIZE) + assert new_key_size.text.strip() == "128" + + +class TestOAEPparams: + + def setup_class(self): + self.oaep_params = md.OAEPparams() + + def testAccessors(self): + """Test for OAEPparams accessors""" + self.oaep_params.text = "9lWu3Q==" + new_oaep_params = md.oae_pparams_from_string(self.oaep_params.to_string()) + assert new_oaep_params.text.strip() == "9lWu3Q==" + + def testUsingTestData(self): + """Test for oae_pparams_from_string() using test data.""" + new_oaep_params = md.oae_pparams_from_string(md_data.TEST_OAEP_PARAMS) + assert new_oaep_params.text.strip() == "9lWu3Q==" + + +class TestEncryptionMethod: + + def setup_class(self): + self.encryption_method = md.EncryptionMethod() + + def testAccessors(self): + """Test for EncryptionMethod accessors""" + self.encryption_method.algorithm = ( + "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p") + self.encryption_method.oaep_params = md.OAEPparams(text="9lWu3Q==") + self.encryption_method.digest_method = ds.DigestMethod( + algorithm="http://www.w3.org/2000/09/xmldsig#sha1") + new_encryption_method = md.encryption_method_from_string( + self.encryption_method.to_string()) + assert new_encryption_method.algorithm == "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" + assert new_encryption_method.oaep_params.text.strip() == "9lWu3Q==" + assert new_encryption_method.digest_method.algorithm == "http://www.w3.org/2000/09/xmldsig#sha1" + + def testUsingTestData(self): + """Test for encryption_method_from_string() using test data.""" + new_encryption_method = md.encryption_method_from_string( + md_data.TEST_ENCRYPTION_METHOD) + assert new_encryption_method.algorithm == "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" + assert new_encryption_method.oaep_params.text.strip() == "9lWu3Q==" + assert new_encryption_method.digest_method.algorithm == "http://www.w3.org/2000/09/xmldsig#sha1" + + +class TestKeyDescriptor: + + def setup_class(self): + self.key_descriptor = md.KeyDescriptor() + + def testAccessors(self): + """Test for KeyDescriptor accessors""" + + self.key_descriptor.use = "signing" + self.key_descriptor.key_info = ds.key_info_from_string( + ds_data.TEST_KEY_INFO) + self.key_descriptor.encryption_method.append(md.encryption_method_from_string( + md_data.TEST_ENCRYPTION_METHOD)) + new_key_descriptor = md.key_descriptor_from_string( + self.key_descriptor.to_string()) + assert new_key_descriptor.use == "signing" + assert isinstance(new_key_descriptor.key_info, ds.KeyInfo) + assert isinstance(new_key_descriptor.encryption_method[0], + md.EncryptionMethod) + + def testUsingTestData(self): + """Test for key_descriptor_from_string() using test data.""" + new_key_descriptor = md.key_descriptor_from_string( + md_data.TEST_KEY_DESCRIPTOR) + assert new_key_descriptor.use == "signing" + assert isinstance(new_key_descriptor.key_info, ds.KeyInfo) + assert isinstance(new_key_descriptor.encryption_method[0], + md.EncryptionMethod) + + +class TestRoleDescriptor: + def setup_class(self): + self.role_descriptor = md.RoleDescriptor() + + def testAccessors(self): + """Test for RoleDescriptor accessors""" + self.role_descriptor.id = "ID" + self.role_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.role_descriptor.cache_duration = "10:00:00:00" + self.role_descriptor.protocol_support_enumeration = samlp.NAMESPACE + self.role_descriptor.error_url = "http://www.example.com/errorURL" + self.role_descriptor.signature = ds.get_empty_signature() + self.role_descriptor.extensions = md.Extensions() + self.role_descriptor.key_descriptor.append(md.key_descriptor_from_string( + md_data.TEST_KEY_DESCRIPTOR)) + self.role_descriptor.organization = md.Organization() + self.role_descriptor.contact_person.append(md.ContactPerson()) + + new_role_descriptor = md.role_descriptor_from_string( + self.role_descriptor.to_string()) + assert new_role_descriptor.id == "ID" + assert new_role_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_role_descriptor.cache_duration == "10:00:00:00" + assert new_role_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_role_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_role_descriptor.signature, ds.Signature) + assert isinstance(new_role_descriptor.extensions, md.Extensions) + assert isinstance(new_role_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_role_descriptor.organization, md.Organization) + assert isinstance(new_role_descriptor.contact_person[0], + md.ContactPerson) + + def testUsingTestData(self): + """Test for role_descriptor_from_string() using test data.""" + new_role_descriptor = md.role_descriptor_from_string( + md_data.TEST_ROLE_DESCRIPTOR) + assert new_role_descriptor.id == "ID" + assert new_role_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_role_descriptor.cache_duration == "10:00:00:00" + assert new_role_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_role_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_role_descriptor.signature, ds.Signature) + assert isinstance(new_role_descriptor.extensions, md.Extensions) + assert isinstance(new_role_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_role_descriptor.organization, md.Organization) + assert isinstance(new_role_descriptor.contact_person[0], + md.ContactPerson) + +class TestSSODescriptor: + def setup_class(self): + self.sso_descriptor = md.SSODescriptor() + + def testAccessors(self): + """Test for SSODescriptor accessors""" + self.sso_descriptor.id = "ID" + self.sso_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.sso_descriptor.cache_duration = "10:00:00:00" + self.sso_descriptor.protocol_support_enumeration = samlp.NAMESPACE + self.sso_descriptor.error_url = "http://www.example.com/errorURL" + self.sso_descriptor.signature = ds.get_empty_signature() + self.sso_descriptor.extensions = md.Extensions() + self.sso_descriptor.key_descriptor.append(md.key_descriptor_from_string( + md_data.TEST_KEY_DESCRIPTOR)) + self.sso_descriptor.organization = md.Organization() + self.sso_descriptor.contact_person.append(md.ContactPerson()) + self.sso_descriptor.artifact_resolution_service.append( + md.ArtifactResolutionService()) + self.sso_descriptor.single_logout_service.append( + md.SingleLogoutService()) + self.sso_descriptor.manage_name_id_service.append( + md.ManageNameIDService()) + self.sso_descriptor.name_id_format.append( + md.NameIDFormat()) + + new_sso_descriptor = md.sso_descriptor_from_string( + self.sso_descriptor.to_string()) + assert new_sso_descriptor.id == "ID" + assert new_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_sso_descriptor.cache_duration == "10:00:00:00" + assert new_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_sso_descriptor.signature, ds.Signature) + assert isinstance(new_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_sso_descriptor.organization, md.Organization) + assert isinstance(new_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance(new_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_sso_descriptor.name_id_format[0], + md.NameIDFormat) + + def testUsingTestData(self): + """Test for sso_descriptor_from_string() using test data.""" + new_sso_descriptor = md.sso_descriptor_from_string( + md_data.TEST_SSO_DESCRIPTOR) + assert new_sso_descriptor.id == "ID" + assert new_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_sso_descriptor.cache_duration == "10:00:00:00" + assert new_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_sso_descriptor.signature, ds.Signature) + assert isinstance(new_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_sso_descriptor.organization, md.Organization) + assert isinstance(new_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance(new_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_sso_descriptor.name_id_format[0], + md.NameIDFormat) + + +class TestArtifactResolutionService: + + def setup_class(self): + self.i_e = md.ArtifactResolutionService() + + def testAccessors(self): + """Test for ArtifactResolutionService accessors""" + self.i_e.binding = saml2.BINDING_HTTP_POST + self.i_e.location = "http://www.example.com/endpoint" + self.i_e.response_location = "http://www.example.com/response" + self.i_e.index = "1" + self.i_e.is_default = "false" + new_i_e = md.artifact_resolution_service_from_string(self.i_e.to_string()) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + def testUsingTestData(self): + """Test for artifact_resolution_service_from_string() using test data.""" + new_i_e = md.artifact_resolution_service_from_string( + md_data.TEST_ARTIFACT_RESOLUTION_SERVICE) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + +class TestSingleLogout: + + def setup_class(self): + self.endpoint = md.SingleLogoutService() + + def testAccessors(self): + """Test for SingleLogoutService accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + new_endpoint = md.single_logout_service_from_string(self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for single_logout_service_from_string() using test data.""" + new_endpoint = md.single_logout_service_from_string( + md_data.TEST_SINGLE_LOGOUT_SERVICE) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + +class TestManageNameIDService: + + def setup_class(self): + self.endpoint = md.ManageNameIDService() + + def testAccessors(self): + """Test for ManageNameIDService accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + new_endpoint = md.manage_name_id_service_from_string(self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for manage_name_id_service_from_string() using test data.""" + new_endpoint = md.manage_name_id_service_from_string( + md_data.TEST_MANAGE_NAMEID_SERVICE) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + +class TestNameIDFormat: + + def setup_class(self): + self.name_id_format = md.NameIDFormat() + + def testAccessors(self): + """Test for NameIDFormat accessors""" + self.name_id_format.text = saml.NAMEID_FORMAT_EMAILADDRESS + new_name_id_format = md.name_id_format_from_string( + self.name_id_format.to_string()) + assert new_name_id_format.text.strip() == saml.NAMEID_FORMAT_EMAILADDRESS + + def testUsingTestData(self): + """Test for name_id_format_from_string() using test data.""" + new_name_id_format = md.name_id_format_from_string( + md_data.TEST_NAME_ID_FORMAT) + assert new_name_id_format.text.strip() == saml.NAMEID_FORMAT_EMAILADDRESS + + +class TestSingleSignOnService: + + def setup_class(self): + self.endpoint = md.SingleSignOnService() + + def testAccessors(self): + """Test for SingelSignOnService accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + new_endpoint = md.single_sign_on_service_from_string(self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for SingelSignOn_service_from_string() using test data.""" + new_endpoint = md.single_sign_on_service_from_string( + md_data.TEST_SINGLE_SIGN_ON_SERVICE) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + +class TestNameIDMappingService: + + def setup_class(self): + self.endpoint = md.NameIDMappingService() + + def testAccessors(self): + """Test for NameIDMappingService accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + new_endpoint = md.name_id_mapping_service_from_string(self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for name_id_mapping_service_from_string() using test data.""" + new_endpoint = md.name_id_mapping_service_from_string( + md_data.TEST_NAME_ID_MAPPING_SERVICE) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + +class TestAssertionIDRequestService: + + def setup_class(self): + self.endpoint = md.AssertionIDRequestService() + + def testAccessors(self): + """Test for AssertionIDRequestService accessors""" + self.endpoint.binding = saml2.BINDING_HTTP_POST + self.endpoint.location = "http://www.example.com/endpoint" + self.endpoint.response_location = "http://www.example.com/response" + new_endpoint = md.assertion_id_request_service_from_string( + self.endpoint.to_string()) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + + def testUsingTestData(self): + """Test for assertion_id_request_service_from_string() using test data.""" + new_endpoint = md.assertion_id_request_service_from_string( + md_data.TEST_ASSERTION_ID_REQUEST_SERVICE) + assert new_endpoint.binding == saml2.BINDING_HTTP_POST + assert new_endpoint.location == "http://www.example.com/endpoint" + assert new_endpoint.response_location == "http://www.example.com/response" + +class TestAttributeProfile: + + def setup_class(self): + self.attribute_profile = md.AttributeProfile() + + def testAccessors(self): + """Test for AttributeProfile accessors""" + self.attribute_profile.text = saml.PROFILE_ATTRIBUTE_BASIC + new_attribute_profile = md.attribute_profile_from_string( + self.attribute_profile.to_string()) + assert new_attribute_profile.text.strip() == saml.PROFILE_ATTRIBUTE_BASIC + + def testUsingTestData(self): + """Test for name_id_format_from_string() using test data.""" + new_attribute_profile = md.attribute_profile_from_string( + md_data.TEST_ATTRIBUTE_PROFILE) + assert new_attribute_profile.text.strip() == saml.PROFILE_ATTRIBUTE_BASIC + + +class TestIDPSSODescriptor: + def setup_class(self): + self.idp_sso_descriptor = md.IDPSSODescriptor() + + def testAccessors(self): + """Test for IDPSSODescriptor accessors""" + self.idp_sso_descriptor.id = "ID" + self.idp_sso_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.idp_sso_descriptor.cache_duration = "10:00:00:00" + self.idp_sso_descriptor.protocol_support_enumeration = \ + samlp.NAMESPACE + self.idp_sso_descriptor.error_url = "http://www.example.com/errorURL" + self.idp_sso_descriptor.signature = ds.get_empty_signature() + self.idp_sso_descriptor.extensions = md.Extensions() + self.idp_sso_descriptor.key_descriptor.append(md.key_descriptor_from_string( + md_data.TEST_KEY_DESCRIPTOR)) + self.idp_sso_descriptor.organization = md.Organization() + self.idp_sso_descriptor.contact_person.append(md.ContactPerson()) + self.idp_sso_descriptor.artifact_resolution_service.append( + md.ArtifactResolutionService()) + self.idp_sso_descriptor.single_logout_service.append( + md.SingleLogoutService()) + self.idp_sso_descriptor.manage_name_id_service.append( + md.ManageNameIDService()) + self.idp_sso_descriptor.name_id_format.append( + md.NameIDFormat()) + self.idp_sso_descriptor.want_authn_requests_signed = 'true' + self.idp_sso_descriptor.single_sign_on_service.append( + md.SingleSignOnService()) + self.idp_sso_descriptor.name_id_mapping_service.append( + md.NameIDMappingService()) + self.idp_sso_descriptor.assertion_id_request_service.append( + md.AssertionIDRequestService()) + self.idp_sso_descriptor.attribute_profile.append( + md.AttributeProfile()) + self.idp_sso_descriptor.attribute.append(saml.Attribute()) + + new_idp_sso_descriptor = md.idpsso_descriptor_from_string( + self.idp_sso_descriptor.to_string()) + assert new_idp_sso_descriptor.id == "ID" + assert new_idp_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_idp_sso_descriptor.cache_duration == "10:00:00:00" + assert new_idp_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_idp_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_idp_sso_descriptor.signature, ds.Signature) + assert isinstance(new_idp_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_idp_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_idp_sso_descriptor.organization, + md.Organization) + assert isinstance(new_idp_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance( + new_idp_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_idp_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_idp_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_idp_sso_descriptor.name_id_format[0], + md.NameIDFormat) + assert new_idp_sso_descriptor.want_authn_requests_signed == "true" + assert isinstance(new_idp_sso_descriptor.single_sign_on_service[0], + md.SingleSignOnService) + assert isinstance(new_idp_sso_descriptor.name_id_mapping_service[0], + md.NameIDMappingService) + assert isinstance( + new_idp_sso_descriptor.assertion_id_request_service[0], + md.AssertionIDRequestService) + assert isinstance(new_idp_sso_descriptor.attribute_profile[0], + md.AttributeProfile) + assert isinstance(new_idp_sso_descriptor.attribute[0], + saml.Attribute) + + def testUsingTestData(self): + """Test for idpsso_descriptor_from_string() using test data.""" + new_idp_sso_descriptor = md.idpsso_descriptor_from_string( + md_data.TEST_IDP_SSO_DESCRIPTOR) + assert new_idp_sso_descriptor.id == "ID" + assert new_idp_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_idp_sso_descriptor.cache_duration == "10:00:00:00" + assert new_idp_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_idp_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_idp_sso_descriptor.signature, ds.Signature) + assert isinstance(new_idp_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_idp_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_idp_sso_descriptor.organization, + md.Organization) + assert isinstance(new_idp_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance( + new_idp_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_idp_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_idp_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_idp_sso_descriptor.name_id_format[0], + md.NameIDFormat) + assert new_idp_sso_descriptor.want_authn_requests_signed == "true" + assert isinstance(new_idp_sso_descriptor.single_sign_on_service[0], + md.SingleSignOnService) + assert isinstance(new_idp_sso_descriptor.name_id_mapping_service[0], + md.NameIDMappingService) + assert isinstance( + new_idp_sso_descriptor.assertion_id_request_service[0], + md.AssertionIDRequestService) + assert isinstance(new_idp_sso_descriptor.attribute_profile[0], + md.AttributeProfile) + assert isinstance(new_idp_sso_descriptor.attribute[0], + saml.Attribute) + + +class TestAssertionConsumerService: + + def setup_class(self): + self.i_e = md.AssertionConsumerService() + + def testAccessors(self): + """Test for AssertionConsumerService accessors""" + self.i_e.binding = saml2.BINDING_HTTP_POST + self.i_e.location = "http://www.example.com/endpoint" + self.i_e.response_location = "http://www.example.com/response" + self.i_e.index = "1" + self.i_e.is_default = "false" + new_i_e = md.assertion_consumer_service_from_string(self.i_e.to_string()) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + def testUsingTestData(self): + """Test for assertion_consumer_service_from_string() using test data.""" + new_i_e = md.assertion_consumer_service_from_string( + md_data.TEST_ASSERTION_CONSUMER_SERVICE) + assert new_i_e.binding == saml2.BINDING_HTTP_POST + assert new_i_e.location == "http://www.example.com/endpoint" + assert new_i_e.response_location == "http://www.example.com/response" + assert new_i_e.index == "1" + assert new_i_e.is_default == "false" + + +class TestRequestedAttribute: + + def setup_class(self): + self.requested_attribute = md.RequestedAttribute() + + def testAccessors(self): + """Test for RequestedAttribute accessors""" + assert isinstance(self.requested_attribute, saml.Attribute) + assert isinstance(self.requested_attribute, md.RequestedAttribute) + assert self.requested_attribute.is_required is None + self.requested_attribute.is_required = "true" + new_requested_attribute = md.requested_attribute_from_string( + self.requested_attribute.to_string()) + assert new_requested_attribute.is_required == "true" + assert isinstance(new_requested_attribute, saml.Attribute) + assert isinstance(new_requested_attribute, md.RequestedAttribute) + + def testUsingTestData(self): + """Test for requested_attribute_from_string() using test data.""" + new_requested_attribute = md.requested_attribute_from_string( + md_data.TEST_REQUESTED_ATTRIBUTE) + assert new_requested_attribute.is_required == "true" + assert isinstance(new_requested_attribute, saml.Attribute) + assert isinstance(new_requested_attribute, md.RequestedAttribute) + + +class TestServiceName: + + def setup_class(self): + self.service_name = md.ServiceName() + + def testAccessors(self): + """Test for ServiceName accessors""" + self.service_name.lang = "en" + self.service_name.text = "SIOS mail" + new_service_name = md.service_name_from_string(self.service_name.to_string()) + assert new_service_name.lang == "en" + assert new_service_name.text.strip() == "SIOS mail" + + def testUsingTestData(self): + """Test for organization_name_from_string() using test data.""" + new_service_name = md.service_name_from_string(md_data.TEST_SERVICE_NAME) + assert new_service_name.lang == "en" + assert new_service_name.text.strip() == "SIOS mail" + + +class TestServiceDescription: + + def setup_class(self): + self.service_description = md.ServiceDescription() + + def testAccessors(self): + """Test for ServiceDescription accessors""" + self.service_description.lang = "en" + self.service_description.text = "SIOS mail service" + new_service_description = md.service_description_from_string( + self.service_description.to_string()) + assert new_service_description.lang == "en" + assert new_service_description.text.strip() == "SIOS mail service" + + def testUsingTestData(self): + """Test for organization_name_from_string() using test data.""" + new_service_description = md.service_description_from_string( + md_data.TEST_SERVICE_DESCRIPTION) + assert new_service_description.lang == "en" + assert new_service_description.text.strip() == "SIOS mail service" + + +class TestAttributeConsumingService: + + def setup_class(self): + self.attribute_consuming_service = md.AttributeConsumingService() + + def testAccessors(self): + """Test for AttributeConsumingService accessors""" + self.attribute_consuming_service.service_name.append(md.ServiceName()) + self.attribute_consuming_service.service_description.append( + md.ServiceDescription()) + self.attribute_consuming_service.requested_attribute.append( + md.RequestedAttribute()) + self.attribute_consuming_service.index = "1" + self.attribute_consuming_service.is_default = "true" + + new_attribute_consuming_service = md.attribute_consuming_service_from_string( + self.attribute_consuming_service.to_string()) + assert new_attribute_consuming_service.index == "1" + assert new_attribute_consuming_service.is_default == "true" + assert isinstance(new_attribute_consuming_service.service_name[0], + md.ServiceName) + assert isinstance( + new_attribute_consuming_service.service_description[0], + md.ServiceDescription) + assert isinstance( + new_attribute_consuming_service.requested_attribute[0], + md.RequestedAttribute) + + def testUsingTestData(self): + """Test for attribute_consuming_service_from_string() using test data.""" + new_attribute_consuming_service = md.attribute_consuming_service_from_string( + md_data.TEST_ATTRIBUTE_CONSUMING_SERVICE) + assert new_attribute_consuming_service.index == "1" + assert new_attribute_consuming_service.is_default == "true" + assert isinstance(new_attribute_consuming_service.service_name[0], + md.ServiceName) + assert isinstance( + new_attribute_consuming_service.service_description[0], + md.ServiceDescription) + assert isinstance( + new_attribute_consuming_service.requested_attribute[0], + md.RequestedAttribute) + + +class TestSPSSODescriptor: + def setup_class(self): + self.sp_sso_descriptor = md.SPSSODescriptor() + + def testAccessors(self): + """Test for SPSSODescriptor accessors""" + self.sp_sso_descriptor.id = "ID" + self.sp_sso_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.sp_sso_descriptor.cache_duration = "10:00:00:00" + self.sp_sso_descriptor.protocol_support_enumeration = \ + samlp.NAMESPACE + self.sp_sso_descriptor.error_url = "http://www.example.com/errorURL" + self.sp_sso_descriptor.signature = ds.get_empty_signature() + self.sp_sso_descriptor.extensions = md.Extensions() + self.sp_sso_descriptor.key_descriptor.append(md.key_descriptor_from_string( + md_data.TEST_KEY_DESCRIPTOR)) + self.sp_sso_descriptor.organization = md.Organization() + self.sp_sso_descriptor.contact_person.append(md.ContactPerson()) + self.sp_sso_descriptor.artifact_resolution_service.append( + md.ArtifactResolutionService()) + self.sp_sso_descriptor.single_logout_service.append( + md.SingleLogoutService()) + self.sp_sso_descriptor.manage_name_id_service.append( + md.ManageNameIDService()) + self.sp_sso_descriptor.name_id_format.append( + md.NameIDFormat()) + self.sp_sso_descriptor.authn_requests_signed = "true" + self.sp_sso_descriptor.want_assertions_signed = "true" + self.sp_sso_descriptor.assertion_consumer_service.append( + md.AssertionConsumerService()) + self.sp_sso_descriptor.attribute_consuming_service.append( + md.AttributeConsumingService()) + + print self.sp_sso_descriptor + new_sp_sso_descriptor = md.spsso_descriptor_from_string( + self.sp_sso_descriptor.to_string()) + print new_sp_sso_descriptor + assert new_sp_sso_descriptor.id == "ID" + assert new_sp_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_sp_sso_descriptor.cache_duration == "10:00:00:00" + assert new_sp_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_sp_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_sp_sso_descriptor.signature, ds.Signature) + assert isinstance(new_sp_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_sp_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_sp_sso_descriptor.organization, + md.Organization) + assert isinstance(new_sp_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance( + new_sp_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_sp_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_sp_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_sp_sso_descriptor.name_id_format[0], + md.NameIDFormat) + assert new_sp_sso_descriptor.authn_requests_signed == "true" + assert new_sp_sso_descriptor.want_assertions_signed == "true" + assert isinstance( + new_sp_sso_descriptor.assertion_consumer_service[0], + md.AssertionConsumerService) + assert isinstance( + new_sp_sso_descriptor.attribute_consuming_service[0], + md.AttributeConsumingService) + + def testUsingTestData(self): + """Test for spsso_descriptor_from_string() using test data.""" + new_sp_sso_descriptor = md.spsso_descriptor_from_string( + md_data.TEST_SP_SSO_DESCRIPTOR) + assert new_sp_sso_descriptor.id == "ID" + assert new_sp_sso_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_sp_sso_descriptor.cache_duration == "10:00:00:00" + assert new_sp_sso_descriptor.protocol_support_enumeration == samlp.NAMESPACE + assert new_sp_sso_descriptor.error_url == "http://www.example.com/errorURL" + assert isinstance(new_sp_sso_descriptor.signature, ds.Signature) + assert isinstance(new_sp_sso_descriptor.extensions, md.Extensions) + assert isinstance(new_sp_sso_descriptor.key_descriptor[0], + md.KeyDescriptor) + assert isinstance(new_sp_sso_descriptor.organization, + md.Organization) + assert isinstance(new_sp_sso_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance( + new_sp_sso_descriptor.artifact_resolution_service[0], + md.ArtifactResolutionService) + assert isinstance(new_sp_sso_descriptor.single_logout_service[0], + md.SingleLogoutService) + assert isinstance(new_sp_sso_descriptor.manage_name_id_service[0], + md.ManageNameIDService) + assert isinstance(new_sp_sso_descriptor.name_id_format[0], + md.NameIDFormat) + assert new_sp_sso_descriptor.authn_requests_signed == "true" + assert new_sp_sso_descriptor.want_assertions_signed == "true" + assert isinstance( + new_sp_sso_descriptor.assertion_consumer_service[0], + md.AssertionConsumerService) + assert isinstance( + new_sp_sso_descriptor.attribute_consuming_service[0], + md.AttributeConsumingService) + + +class TestEntityDescriptor: + def setup_class(self): + self.entity_descriptor = md.EntityDescriptor() + + def testAccessors(self): + """Test for RoleDescriptor accessors""" + self.entity_descriptor.id = "ID" + self.entity_descriptor.entity_id = "entityID" + self.entity_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.entity_descriptor.cache_duration = "10:00:00:00" + + self.entity_descriptor.signature = ds.get_empty_signature() + self.entity_descriptor.extensions = md.Extensions() + self.entity_descriptor.role_descriptor.append(md.RoleDescriptor()) + self.entity_descriptor.idp_sso_descriptor.append(md.IDPSSODescriptor()) + self.entity_descriptor.sp_sso_descriptor.append(md.SPSSODescriptor()) + self.entity_descriptor.organization = md.Organization() + self.entity_descriptor.contact_person.append(md.ContactPerson()) + self.entity_descriptor.additional_metadata_location.append( + md.AdditionalMetadataLocation()) + + new_entity_descriptor = md.entity_descriptor_from_string( + self.entity_descriptor.to_string()) + assert new_entity_descriptor.id == "ID" + assert new_entity_descriptor.entity_id == "entityID" + assert new_entity_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_entity_descriptor.cache_duration == "10:00:00:00" + assert isinstance(new_entity_descriptor.signature, ds.Signature) + assert isinstance(new_entity_descriptor.extensions, md.Extensions) + assert isinstance(new_entity_descriptor.role_descriptor[0], + md.RoleDescriptor) + assert isinstance(new_entity_descriptor.idp_sso_descriptor[0], + md.IDPSSODescriptor) + assert isinstance(new_entity_descriptor.sp_sso_descriptor[0], + md.SPSSODescriptor) + assert isinstance(new_entity_descriptor.organization, + md.Organization) + assert isinstance(new_entity_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance( + new_entity_descriptor.additional_metadata_location[0], + md.AdditionalMetadataLocation) + + def testUsingTestData(self): + """Test for entity_descriptor_from_string() using test data.""" + new_entity_descriptor = md.entity_descriptor_from_string( + md_data.TEST_ENTITY_DESCRIPTOR) + assert new_entity_descriptor.id == "ID" + assert new_entity_descriptor.entity_id == "entityID" + assert new_entity_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_entity_descriptor.cache_duration == "10:00:00:00" + assert isinstance(new_entity_descriptor.signature, ds.Signature) + assert isinstance(new_entity_descriptor.extensions, md.Extensions) + assert isinstance(new_entity_descriptor.role_descriptor[0], + md.RoleDescriptor) + assert isinstance(new_entity_descriptor.idp_sso_descriptor[0], + md.IDPSSODescriptor) + assert isinstance(new_entity_descriptor.sp_sso_descriptor[0], + md.SPSSODescriptor) + assert isinstance(new_entity_descriptor.organization, + md.Organization) + assert isinstance(new_entity_descriptor.contact_person[0], + md.ContactPerson) + assert isinstance(new_entity_descriptor.additional_metadata_location[0], + md.AdditionalMetadataLocation) + + +class TestEntitiesDescriptor: + def setup_class(self): + self.entities_descriptor = md.EntitiesDescriptor() + + def testAccessors(self): + """Test for EntitiesDescriptor accessors""" + self.entities_descriptor.id = "ID" + self.entities_descriptor.name = "name" + self.entities_descriptor.valid_until = "2008-09-14T01:05:02Z" + self.entities_descriptor.cache_duration = "10:00:00:00" + + self.entities_descriptor.signature = ds.get_empty_signature() + self.entities_descriptor.extensions = md.Extensions() + self.entities_descriptor.entity_descriptor.append(md.EntityDescriptor()) + self.entities_descriptor.entities_descriptor.append( + md.EntitiesDescriptor()) + + new_entities_descriptor = md.entities_descriptor_from_string( + self.entities_descriptor.to_string()) + assert new_entities_descriptor.id == "ID" + assert new_entities_descriptor.name == "name" + assert new_entities_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_entities_descriptor.cache_duration == "10:00:00:00" + assert isinstance(new_entities_descriptor.signature, ds.Signature) + assert isinstance(new_entities_descriptor.extensions, md.Extensions) + assert isinstance(new_entities_descriptor.entity_descriptor[0], + md.EntityDescriptor) + assert isinstance(new_entities_descriptor.entities_descriptor[0], + md.EntitiesDescriptor) + + def testUsingTestData(self): + """Test for entities_descriptor_from_string() using test data.""" + new_entities_descriptor = md.entities_descriptor_from_string( + md_data.TEST_ENTITIES_DESCRIPTOR) + assert new_entities_descriptor.id == "ID" + assert new_entities_descriptor.name == "name" + assert new_entities_descriptor.valid_until == "2008-09-14T01:05:02Z" + assert new_entities_descriptor.cache_duration == "10:00:00:00" + assert isinstance(new_entities_descriptor.signature, ds.Signature) + assert isinstance(new_entities_descriptor.extensions, md.Extensions) + assert isinstance(new_entities_descriptor.entity_descriptor[0], + md.EntityDescriptor) + assert isinstance(new_entities_descriptor.entities_descriptor[0], + md.EntitiesDescriptor) + + diff --git a/tests/test_3_metadata.py b/tests/test_3_metadata.py new file mode 100644 index 0000000..afb215f --- /dev/null +++ b/tests/test_3_metadata.py @@ -0,0 +1,359 @@ +import os + +from saml2 import metadata, utils +from saml2 import NAMESPACE as SAML2_NAMESPACE +from saml2 import BINDING_SOAP +from saml2 import md, saml, samlp +from saml2 import time_util +from saml2.saml import NAMEID_FORMAT_TRANSIENT + +SWAMI_METADATA = "swamid-kalmar-1.0.xml" +INCOMMON_METADATA = "InCommon-metadata.xml" +EXAMPLE_METADATA = "metadata_example.xml" +SWITCH_METADATA = "metadata.aaitest.xml" +SP_METADATA = "metasp.xml" + +def _eq(l1,l2): + return set(l1) == set(l2) + +def _read_file(name): + try: + return open(name).read() + except IOError: + name = "tests/"+name + return open(name).read() + +def _read_lines(name): + try: + return open(name).readlines() + except IOError: + name = "tests/"+name + return open(name).readlines() + +def test_swami_1(): + md = metadata.MetaData() + md.import_metadata(_read_file(SWAMI_METADATA)) + print len(md.entity) + assert len(md.entity) + idps = dict([(id,ent["idp_sso"]) for id,ent in md.entity.items() \ + if "idp_sso" in ent]) + print idps + assert idps.keys() + idp_sso = md.single_sign_on_services( + 'https://idp.umu.se/saml2/idp/metadata.php') + assert md.name('https://idp.umu.se/saml2/idp/metadata.php') == ( + u'Ume\xe5 university (New SAML2)') + assert len(idp_sso) == 1 + assert idp_sso == ['https://idp.umu.se/saml2/idp/SSOService.php'] + ssocerts = md.certs('https://idp.umu.se/saml2/idp/SSOService.php') + print ssocerts + assert len(ssocerts) == 1 + +def test_incommon_1(): + md = metadata.MetaData() + md.import_metadata(_read_file(INCOMMON_METADATA)) + print len(md.entity) + assert len(md.entity) == 442 + idps = dict([ + (id,ent["idp_sso"]) for id,ent in md.entity.items() if "idp_sso" in ent]) + print idps.keys() + assert len(idps) == 53 # !!!!???? < 10% + idp_sso = md.single_sign_on_services('urn:mace:incommon:uiuc.edu') + assert idp_sso == [] + idp_sso = md.single_sign_on_services('urn:mace:incommon:alaska.edu') + assert len(idp_sso) == 1 + print idp_sso + assert idp_sso == ['https://idp.alaska.edu/idp/profile/SAML2/Redirect/SSO'] + +def test_example(): + md = metadata.MetaData() + md.import_metadata(_read_file(EXAMPLE_METADATA)) + print len(md.entity) + assert len(md.entity) == 1 + idps = dict([(id,ent["idp_sso"]) for id,ent in md.entity.items() \ + if "idp_sso" in ent]) + assert idps.keys() == [ + 'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php'] + certs = md.certs( + 'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php') + assert len(certs) == 1 + assert isinstance(certs[0], tuple) + assert len(certs[0]) == 2 + +def test_switch_1(): + md = metadata.MetaData() + md.import_metadata(_read_file(SWITCH_METADATA)) + print len(md.entity) + assert len(md.entity) == 90 + idps = dict([(id,ent["idp_sso"]) for id,ent in md.entity.items() \ + if "idp_sso" in ent]) + print idps.keys() + idp_sso = md.single_sign_on_services( + 'https://aai-demo-idp.switch.ch/idp/shibboleth') + assert len(idp_sso) == 1 + print idp_sso + assert idp_sso == [ + 'https://aai-demo-idp.switch.ch/idp/profile/SAML2/Redirect/SSO'] + assert len(idps) == 16 + aas = dict([(id,ent["attribute_authority"]) for id,ent in md.entity.items() \ + if "attribute_authority" in ent]) + print aas.keys() + aads = aas['https://aai-demo-idp.switch.ch/idp/shibboleth'] + assert len(aads) == 1 + aad = aads[0] + assert len(aad.attribute_service) == 1 + assert len(aad.name_id_format) == 2 + dual = dict([(id,ent) for id,ent in md.entity.items() \ + if "idp_sso" in ent and "sp_sso" in ent]) + print len(dual) + assert len(dual) == 0 + +def test_sp_metadata(): + md = metadata.MetaData() + md.import_metadata(_read_file(SP_METADATA)) + + print md.entity + assert len(md.entity) == 1 + assert md.entity.keys() == ['urn:mace:umu.se:saml:roland:sp'] + assert md.entity['urn:mace:umu.se:saml:roland:sp'].keys() == [ + "organization","sp_sso"] + print md.entity['urn:mace:umu.se:saml:roland:sp']["sp_sso"][0].keyswv() + (req,opt) = md.attribute_consumer('urn:mace:umu.se:saml:roland:sp') + print req + assert len(req) == 3 + assert len(opt) == 1 + assert opt[0].name == 'urn:oid:2.5.4.12' + assert opt[0].friendly_name == 'title' + assert _eq([n.name for n in req],['urn:oid:2.5.4.4', 'urn:oid:2.5.4.42', + 'urn:oid:0.9.2342.19200300.100.1.3']) + assert _eq([n.friendly_name for n in req],['surName', 'givenName', 'mail']) + +# ------------ Constructing metaval ---------------------------------------- + +def test_construct_organisation_name(): + o = md.Organization() + utils.make_vals({"text":"Exempel AB", "lang":"se"}, + md.OrganizationName, o, "organization_name") + print o + assert str(o) == """ +Exempel AB""" + +def test_make_int_value(): + val = utils.make_vals( 1, saml.AttributeValue, part=True) + assert isinstance(val, saml.AttributeValue) + assert val.text == "1" + +def test_make_true_value(): + val = utils.make_vals( True, saml.AttributeValue, part=True ) + assert isinstance(val, saml.AttributeValue) + assert val.text == "True" + +def test_make_false_value(): + val = utils.make_vals( False, saml.AttributeValue, part=True ) + assert isinstance(val, saml.AttributeValue) + assert val.text == "False" + +NO_VALUE = """ +""" + +def test_make_no_value(): + val = utils.make_vals( None, saml.AttributeValue, part=True ) + assert isinstance(val, saml.AttributeValue) + assert val.text == None + print val + assert "%s" % val == NO_VALUE + +def test_make_string(): + val = utils.make_vals( "example", saml.AttributeValue, part=True ) + assert isinstance(val, saml.AttributeValue) + assert val.text == "example" + +def test_make_list_of_strings(): + attr = saml.Attribute() + vals = ["foo", "bar"] + val = utils.make_vals(vals, saml.AttributeValue, attr, + "attribute_value") + assert attr.keyswv() == ["attribute_value"] + print attr.attribute_value + assert _eq([val.text for val in attr.attribute_value], vals) + +def test_make_dict(): + vals = ["foo", "bar"] + attrval = { "attribute_value": vals} + attr = utils.make_vals(attrval, saml.Attribute, part=True) + assert attr.keyswv() == ["attribute_value"] + assert _eq([val.text for val in attr.attribute_value], vals) + +# ------------ Constructing metadata ---------------------------------------- + +def test_construct_contact(): + c = utils.make_instance(md.ContactPerson, { + "given_name":"Roland", + "sur_name": "Hedberg", + "email_address": "roland@catalogix.se", + }) + print c + assert c.given_name.text == "Roland" + assert c.sur_name.text == "Hedberg" + assert c.email_address[0].text == "roland@catalogix.se" + assert _eq(c.keyswv(), ["given_name","sur_name","email_address"]) + + +def test_construct_organisation(): + c = utils.make_instance( md.Organization, { + "organization_name": ["Example Co.", + {"text":"Exempel AB", "lang":"se"}], + "organization_url": "http://www.example.com/" + }) + + assert _eq(c.keyswv(), ["organization_name","organization_url"]) + assert len(c.organization_name) == 2 + org_names = [on.text for on in c.organization_name] + assert _eq(org_names,["Exempel AB","Example Co."]) + assert len(c.organization_url) == 1 + +def test_construct_entity_descr_1(): + ed = utils.make_instance(md.EntityDescriptor, + {"organization": { + "organization_name":"Catalogix", + "organization_url": "http://www.catalogix.se/"}, + "entity_id": "urn:mace:catalogix.se:sp1", + }) + + assert ed.entity_id == "urn:mace:catalogix.se:sp1" + org = ed.organization + assert _eq(org.keyswv(), ["organization_name","organization_url"]) + assert len(org.organization_name) == 1 + assert org.organization_name[0].text == "Catalogix" + assert org.organization_url[0].text == "http://www.catalogix.se/" + +def test_construct_entity_descr_2(): + ed = utils.make_instance(md.EntityDescriptor, + {"organization": { + "organization_name":"Catalogix", + "organization_url": "http://www.catalogix.se/"}, + "entity_id": "urn:mace:catalogix.se:sp1", + "contact_person": { + "given_name":"Roland", + "sur_name": "Hedberg", + "email_address": "roland@catalogix.se", + } + }) + + assert _eq(ed.keyswv(), ["entity_id", "contact_person", "organization"]) + assert ed.entity_id == "urn:mace:catalogix.se:sp1" + org = ed.organization + assert _eq(org.keyswv(), ["organization_name", "organization_url"]) + assert len(org.organization_name) == 1 + assert org.organization_name[0].text == "Catalogix" + assert org.organization_url[0].text == "http://www.catalogix.se/" + assert len(ed.contact_person) == 1 + c = ed.contact_person[0] + assert c.given_name.text == "Roland" + assert c.sur_name.text == "Hedberg" + assert c.email_address[0].text == "roland@catalogix.se" + assert _eq(c.keyswv(), ["given_name","sur_name","email_address"]) + +def test_construct_key_descriptor(): + cert = "".join(_read_lines("test.pem")[1:-1]).strip() + spec = { + "use": "signing", + "key_info" : { + "x509_data": { + "x509_certificate": cert + } + } + } + kd = utils.make_instance(md.KeyDescriptor, spec) + assert _eq(kd.keyswv(), ["use", "key_info"]) + assert kd.use == "signing" + ki = kd.key_info + assert _eq(ki.keyswv(), ["x509_data"]) + assert len(ki.x509_data) == 1 + data = ki.x509_data[0] + assert _eq(data.keyswv(), ["x509_certificate"]) + assert len(data.x509_certificate) == 1 + assert len(data.x509_certificate[0].text.strip()) == len(cert) + +def test_construct_key_descriptor_with_key_name(): + cert = "".join(_read_lines("test.pem")[1:-1]).strip() + spec = { + "use": "signing", + "key_info" : { + "key_name": "example.com", + "x509_data": { + "x509_certificate": cert + } + } + } + kd = utils.make_instance(md.KeyDescriptor, spec) + assert _eq(kd.keyswv(), ["use", "key_info"]) + assert kd.use == "signing" + ki = kd.key_info + assert _eq(ki.keyswv(), ["x509_data", "key_name"]) + assert len(ki.key_name) == 1 + assert ki.key_name[0].text.strip() == "example.com" + assert len(ki.x509_data) == 1 + data = ki.x509_data[0] + assert _eq(data.keyswv(), ["x509_certificate"]) + assert len(data.x509_certificate) == 1 + assert len(data.x509_certificate[0].text.strip()) == len(cert) + +def test_construct_AttributeAuthorityDescriptor(): + aad = utils.make_instance( + md.AttributeAuthorityDescriptor, { + "valid_until": time_util.in_a_while(30), # 30 days from now + "id": "aad.example.com", + "protocol_support_enumeration": SAML2_NAMESPACE, + "attribute_service": { + "binding": BINDING_SOAP, + "location": "http://example.com:6543/saml2/aad", + }, + "name_id_format":[ + NAMEID_FORMAT_TRANSIENT, + ], + "key_descriptor": { + "use": "signing", + "key_info" : { + "key_name": "example.com", + } + } + }) + + print aad + assert _eq(aad.keyswv(),["valid_until", "id", "attribute_service", + "name_id_format", "key_descriptor", + "protocol_support_enumeration"]) + assert time_util.str_to_time(aad.valid_until) + assert aad.id == "aad.example.com" + assert aad.protocol_support_enumeration == SAML2_NAMESPACE + assert len(aad.attribute_service) == 1 + atsr = aad.attribute_service[0] + assert _eq(atsr.keyswv(),["binding", "location"]) + assert atsr.binding == BINDING_SOAP + assert atsr.location == "http://example.com:6543/saml2/aad" + assert len(aad.name_id_format) == 1 + nif = aad.name_id_format[0] + assert nif.text.strip() == NAMEID_FORMAT_TRANSIENT + assert len(aad.key_descriptor) == 1 + kdesc = aad.key_descriptor[0] + assert kdesc.use == "signing" + assert kdesc.key_info.key_name[0].text.strip() == "example.com" + +STATUS_RESULT = """ +Error resolving principal""" + +def test_status(): + input = { + "status_code": { + "value": samlp.STATUS_RESPONDER, + "status_code": + { + "value": samlp.STATUS_UNKNOWN_PRINCIPAL, + }, + }, + "status_message": "Error resolving principal", + } + status_text = "%s" % utils.make_instance( samlp.Status, input) + assert status_text == STATUS_RESULT + diff --git a/tests/test_4_server.py b/tests/test_4_server.py new file mode 100644 index 0000000..61f4e1b --- /dev/null +++ b/tests/test_4_server.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from saml2.server import Server +from saml2 import server +from saml2 import samlp, saml, client, utils +from saml2.utils import make_instance, OtherError +from saml2.utils import do_attribute_statement +from py.test import raises +import shelve +import re + +def _eq(l1,l2): + return set(l1) == set(l2) + + +class TestServer(): + def setup_class(self): + try: + self.server = Server("idp.config") + except IOError, e: + self.server = Server("tests/idp.config") + + def test_issuer(self): + issuer = make_instance( saml.Issuer, self.server.issuer()) + assert isinstance(issuer, saml.Issuer) + assert _eq(issuer.keyswv(), ["text","format"]) + assert issuer.format == saml.NAMEID_FORMAT_ENTITY + assert issuer.text == self.server.conf["entityid"] + + + def test_assertion(self): + tmp = utils.kd_assertion( + subject= utils.kd_subject("_aaa", + name_id=saml.NAMEID_FORMAT_TRANSIENT), + attribute_statement = utils.kd_attribute_statement( + attribute=[ + utils.kd_attribute(attribute_value="Derek", + friendly_name="givenName"), + utils.kd_attribute(attribute_value="Jeter", + friendly_name="surName"), + ]), + issuer=self.server.issuer(), + ) + + assertion = make_instance(saml.Assertion, tmp) + assert _eq(assertion.keyswv(),['attribute_statement', 'issuer', 'id', + 'subject', 'issue_instant', 'version']) + assert assertion.version == "2.0" + assert assertion.issuer.text == "urn:mace:example.com:saml:roland:idp" + # + assert len(assertion.attribute_statement) == 1 + attribute_statement = assertion.attribute_statement[0] + assert len(attribute_statement.attribute) == 2 + attr0 = attribute_statement.attribute[0] + attr1 = attribute_statement.attribute[1] + if attr0.attribute_value[0].text == "Derek": + assert attr0.friendly_name == "givenName" + assert attr1.friendly_name == "surName" + assert attr1.attribute_value[0].text == "Jeter" + else: + assert attr1.friendly_name == "givenName" + assert attr1.attribute_value[0].text == "Derek" + assert attr0.friendly_name == "surName" + assert attr0.attribute_value[0].text == "Jeter" + # + subject = assertion.subject + assert _eq(subject.keyswv(),["text", "name_id"]) + assert subject.text == "_aaa" + assert subject.name_id.text == saml.NAMEID_FORMAT_TRANSIENT + + def test_response(self): + tmp = utils.kd_response( + in_response_to="_012345", + destination="https:#www.example.com", + status=utils.kd_success_status(), + assertion=utils.kd_assertion( + subject = utils.kd_subject("_aaa", + name_id=saml.NAMEID_FORMAT_TRANSIENT), + attribute_statement = utils.kd_attribute_statement([ + utils.kd_attribute(attribute_value="Derek", + friendly_name="givenName"), + utils.kd_attribute(attribute_value="Jeter", + friendly_name="surName"), + ]), + issuer=self.server.issuer(), + ), + issuer=self.server.issuer(), + ) + + response = make_instance(samlp.Response, tmp) + print response.keyswv() + assert _eq(response.keyswv(),['destination', 'assertion','status', + 'in_response_to', 'issue_instant', + 'version', 'issuer', 'id']) + assert response.version == "2.0" + assert response.issuer.text == "urn:mace:example.com:saml:roland:idp" + assert response.destination == "https:#www.example.com" + assert response.in_response_to == "_012345" + # + status = response.status + print status + assert status.status_code.value == samlp.STATUS_SUCCESS + + def test_parse_faulty_request(self): + sc = client.Saml2Client({},None) + authn_request = sc.authn_request( + query_id = "1", + destination = "http://www.example.com", + service_url = "http://www.example.org", + spentityid = "urn:mace:example.com:saml:roland:sp", + my_name = "My real name", + ) + + intermed = utils.deflate_and_base64_encode(authn_request) + # should raise an error because faulty spentityid + raises(OtherError,self.server.parse_authn_request,intermed) + + def test_parse_faulty_request_to_err_status(self): + sc = client.Saml2Client({},None) + authn_request = sc.authn_request( + query_id = "1", + destination = "http://www.example.com", + service_url = "http://www.example.org", + spentityid = "urn:mace:example.com:saml:roland:sp", + my_name = "My real name", + ) + + intermed = utils.deflate_and_base64_encode(authn_request) + try: + self.server.parse_authn_request(intermed) + status = None + except OtherError, oe: + print oe.args + status = utils.make_instance(samlp.Status, + utils.kd_status_from_exception(oe)) + + assert status + print status + assert _eq(status.keyswv(), ["status_code", "status_message"]) + assert status.status_message.text == ( + 'ConsumerURL and return destination mismatch') + status_code = status.status_code + assert _eq(status_code.keyswv(), ["status_code","value"]) + assert status_code.value == samlp.STATUS_RESPONDER + assert status_code.status_code.value == samlp.STATUS_UNKNOWN_PRINCIPAL + + def test_parse_ok_request(self): + sc = client.Saml2Client({},None) + authn_request = sc.authn_request( + query_id = "1", + destination = "http://www.example.com", + service_url = "http://localhost:8087/", + spentityid = "urn:mace:example.com:saml:roland:sp", + my_name = "My real name", + ) + + print authn_request + intermed = utils.deflate_and_base64_encode(authn_request) + response = self.server.parse_authn_request(intermed) + + assert response["consumer_url"] == "http://localhost:8087/" + assert response["id"] == "1" + name_id_policy = response["request"].name_id_policy + assert _eq(name_id_policy.keyswv(), ["format", "allow_create"]) + assert name_id_policy.format == saml.NAMEID_FORMAT_TRANSIENT + assert response["sp_entityid"] == "urn:mace:example.com:saml:roland:sp" + + def test_sso_response(self): + resp = self.server.do_sso_response( + "http://localhost:8087/", # consumer_url + "12", # in_response_to + "urn:mace:example.com:saml:roland:sp", # sp_entity_id + {("urn:oid:1.3.6.1.4.1.5923.1.1.1.7", + "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", + "eduPersonEntitlement"):"Jeter"} + ) + + print resp.keyswv() + assert _eq(resp.keyswv(),['status', 'destination', 'assertion', + 'in_response_to', 'issue_instant', + 'version', 'id', 'issuer']) + assert resp.destination == "http://localhost:8087/" + assert resp.in_response_to == "12" + assert resp.status + assert resp.status.status_code.value == samlp.STATUS_SUCCESS + assert resp.assertion + assert len(resp.assertion) == 1 + assertion = resp.assertion[0] + assert len(assertion.authn_statement) == 1 + assert assertion.conditions + assert len(assertion.attribute_statement) == 1 + assert assertion.subject + assert assertion.subject.name_id + assert len(assertion.subject.subject_confirmation) == 1 + confirmation = assertion.subject.subject_confirmation[0] + print confirmation.keyswv() + print confirmation.subject_confirmation_data + assert confirmation.subject_confirmation_data.in_response_to == "12" + + def test_persistence_0(self): + pid1 = self.server.persistent_id( + "urn:mace:example.com:saml:roland:sp", "jeter") + + pid2 = self.server.persistent_id( + "urn:mace:example.com:saml:roland:sp", "jeter") + + print pid1, pid2 + assert pid1 == pid2 + + def test_filter_ava_0(self): + ava = { "givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"]} + + # No restrictions apply + ava = self.server.filter_ava(ava, + "urn:mace:example.com:saml:roland:sp", + [], [], "idp") + + assert _eq(ava.keys(), ["givenName", "surName", "mail"]) + assert ava["givenName"] == ["Derek"] + assert ava["surName"] == ["Jeter"] + assert ava["mail"] == ["derek@nyy.mlb.com"] + + + def test_filter_ava_1(self): + """ No mail address returned """ + self.server.conf["service"]["idp"]["assertions"][ + "urn:mace:example.com:saml:roland:sp"] = { + "lifetime": {"minutes": 5}, + "attribute_restrictions":{ + "givenName": None, + "surName": None, + } + } + + print self.server.conf["service"]["idp"]["assertions"] + + ava = { "givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"]} + + # No restrictions apply + ava = self.server.filter_ava(ava, + "urn:mace:example.com:saml:roland:sp", + [], [], "idp") + + assert _eq(ava.keys(), ["givenName", "surName"]) + assert ava["givenName"] == ["Derek"] + assert ava["surName"] == ["Jeter"] + + def test_filter_ava_2(self): + """ Only mail returned """ + self.server.conf["service"]["idp"]["assertions"][ + "urn:mace:example.com:saml:roland:sp"] = { + "lifetime": {"minutes": 5}, + "attribute_restrictions":{ + "mail": None, + } + } + + print self.server.conf["service"]["idp"]["assertions"] + + ava = { "givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"]} + + # No restrictions apply + ava = self.server.filter_ava(ava, + "urn:mace:example.com:saml:roland:sp", + [], [], "idp") + + assert _eq(ava.keys(), ["mail"]) + assert ava["mail"] == ["derek@nyy.mlb.com"] + + def test_filter_ava_3(self): + """ Only example.com mail addresses returned """ + self.server.conf["service"]["idp"]["assertions"][ + "urn:mace:example.com:saml:roland:sp"] = { + "lifetime": {"minutes": 5}, + "attribute_restrictions":{ + "mail": [re.compile(".*@example\.com$")], + } + } + + print self.server.conf["service"]["idp"]["assertions"] + + ava = { "givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com", "dj@example.com"]} + + # No restrictions apply + ava = self.server.filter_ava(ava, + "urn:mace:example.com:saml:roland:sp", + [], [], "idp") + + assert _eq(ava.keys(), ["mail"]) + assert ava["mail"] == ["dj@example.com"] + + def test_authn_response_0(self): + # reset + del self.server.conf["service"]["idp"]["assertions"][ + "urn:mace:example.com:saml:roland:sp"] + + ava = { "givenName": ["Derek"], "surName": ["Jeter"], + "mail": ["derek@nyy.mlb.com"]} + + resp_str = self.server.authn_response(ava, + "1", "http://local:8087/", + "urn:mace:example.com:saml:roland:sp", + utils.make_instance(samlp.NameIDPolicy, + utils.kd_name_id_policy( + format=saml.NAMEID_FORMAT_TRANSIENT, + allow_create="true")), + "foba0001@example.com") + + response = samlp.response_from_string("\n".join(resp_str)) + print response.keyswv() + assert _eq(response.keyswv(),['status', 'destination', 'assertion', + 'in_response_to', 'issue_instant', 'version', + 'issuer', 'id']) + print response.assertion[0].keyswv() + assert len(response.assertion) == 1 + assert _eq(response.assertion[0].keyswv(), ['authn_statement', + 'attribute_statement', 'subject', 'issue_instant', + 'version', 'conditions', 'id']) + assertion = response.assertion[0] + assert len(assertion.attribute_statement) == 1 + astate = assertion.attribute_statement[0] + print astate + assert len(astate.attribute) == 3 + diff --git a/tests/test_5_cache.py b/tests/test_5_cache.py new file mode 100644 index 0000000..e355725 --- /dev/null +++ b/tests/test_5_cache.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +from saml2.cache import Cache +from saml2.time_util import in_a_while, str_to_time +from saml2.client import SESSION_INFO + +def _eq(l1,l2): + return set(l1) == set(l2) + + +class TestClass: + def setup_class(self): + self.cache = Cache() + + + def test_0(self): + not_on_or_after = str_to_time(in_a_while(days=1)) + session_info = SESSION_INFO.copy() + session_info["ava"] = {"givenName":["Derek"]} + self.cache.set("1234", "abcd", session_info, + not_on_or_after) + + (ava, inactive) = self.cache.get_identity("1234") + assert inactive == [] + assert ava.keys() == ["givenName"] + assert ava["givenName"] == ["Derek"] + + def test_1(self): + not_on_or_after = str_to_time(in_a_while(days=1)) + session_info = SESSION_INFO.copy() + session_info["ava"] = {"surName":["Jeter"]} + self.cache.set("1234", "bcde", session_info, + not_on_or_after) + + (ava, inactive) = self.cache.get_identity("1234") + assert inactive == [] + assert _eq(ava.keys(), ["givenName","surName"]) + assert ava["givenName"] == ["Derek"] + assert ava["surName"] == ["Jeter"] + + def test_2(self): + session_info = self.cache.get("1234","bcde") + ava = session_info["ava"] + assert _eq(ava.keys(), ["surName"]) + assert ava["surName"] == ["Jeter"] + + def test_entities(self): + assert _eq(self.cache.entities("1234"), ["abcd", "bcde"]) + + def test_4(self): + self.cache.reset("1234", "bcde") + assert self.cache.active("1234","bcde") == False + assert self.cache.active("1234","abcd") + + (ava, inactive) = self.cache.get_identity("1234") + assert inactive == ['bcde'] + assert _eq(ava.keys(), ["givenName"]) + assert ava["givenName"] == ["Derek"] + + def test_subjects(self): + assert self.cache.subjects() == ["1234"] + + def test_second_subject(self): + not_on_or_after = str_to_time(in_a_while(days=1)) + session_info = SESSION_INFO.copy() + session_info["ava"] = {"givenName":["Ichiro"], + "surName":["Suzuki"]} + self.cache.set("9876", "abcd", session_info, + not_on_or_after) + + (ava, inactive) = self.cache.get_identity("9876") + assert inactive == [] + assert _eq(ava.keys(), ["givenName","surName"]) + assert ava["givenName"] == ["Ichiro"] + assert ava["surName"] == ["Suzuki"] + assert _eq(self.cache.subjects(), ["1234","9876"]) +