def test_successful_deserialization(self): validators = [SuccessValidator(), SuccessValidator()] request = FakeRequest('<xml></xml>') deserializer = HTTPRequestDeserializer( request, validators=validators, saml_class=FakeSAMLClass) deserialized = deserializer.deserialize() self.assertIsInstance(deserialized, FakeSAMLClass)
def test_missing_issuer(self): # https://github.com/italia/spid-testenv2/issues/133 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') registry = FakeRegistry({ 'http://localhost:8088/': ServiceProviderMetadataFakeLoader([], [(0, 'http://localhost:3000/spid-sso')]) }) for binding, val in list({settings.BINDING_HTTP_POST: sample_requests.fake_signature, settings.BINDING_HTTP_REDIRECT: ''}.items()): request = FakeRequest(sample_requests.missing_issuer) validator = SpidRequestValidator('login', binding, registry, config) with pytest.raises(UnknownEntityIDError) as excinfo: request.saml_request = request.saml_request % (val) validator.validate(request) exc = excinfo.value self.assertEqual( 'Issuer non presente nella AuthnRequest', str(exc))
def test_empty_request(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'') with pytest.raises(XMLFormatValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn('Document is empty', exc.details[0].message)
def test_duplicate_attribute(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'<a attr="value" attr="value"></a>') with pytest.raises(XMLFormatValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn('Attribute attr redefined', exc.details[0].message)
def test_missing_mandatory_attribute(self): validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) request = FakeRequest(sample_requests.missing_issue_instant_attr) with pytest.raises(XMLSchemaValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn("The attribute 'IssueInstant' is required but missing.", exc.details[0].message)
def test_tag_mismatch(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'<a></b>') with pytest.raises(XMLFormatValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn('Opening and ending tag mismatch: a line 1 and b', exc.details[0].message)
def test_not_xml(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'{"this": "is JSON"}') with pytest.raises(XMLFormatValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn( "Start tag expected, '<' not found", exc.details[0].message)
def test_invalid_attribute_format(self): # See: https://github.com/italia/spid-testenv2/issues/63 validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) request = FakeRequest(sample_requests.invalid_id_attr) with pytest.raises(XMLSchemaValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn("is not a valid value of the atomic type 'xs:ID'", exc.details[0].message)
def test_wrong_destination(self): # https://github.com/italia/spid-testenv2/issues/158 config = FakeConfig('http://localhost:9999/sso', 'http://localhost:9999/') registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader([], [(0, 'http://localhost:3000/spid-sso')]) }) for binding, val in list({ settings.BINDING_HTTP_POST: sample_requests.fake_signature, settings.BINDING_HTTP_REDIRECT: '' }.items()): validator = SpidRequestValidator('login', binding, registry, config) request = FakeRequest(sample_requests.wrong_destination) with pytest.raises(SPIDValidationError) as excinfo: request.saml_request = request.saml_request % (val) validator.validate(request) exc = excinfo.value self.assertEqual( 'Il valore dell\'elemento รจ diverso dal valore atteso (http://localhost:9999/):', exc.details[0].message)
def test_multiple_errors(self): validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) request = FakeRequest(sample_requests.multiple_errors) with pytest.raises(XMLSchemaValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 2) self.assertIn("is not a valid value of the atomic type 'xs:ID'", exc.details[0].message) self.assertIn("The attribute 'Version' is required but missing.", exc.details[1].message)
def test_logout_request_http_post_with_reason_attr(self): # https://github.com/italia/spid-testenv2/issues/159 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') request = FakeRequest(sample_requests.logout_with_reason_attr % (sample_requests.fake_signature)) registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader([], [(0, 'http://localhost:3000/spid-sso')]) }) validator = SpidRequestValidator( 'logout', settings.BINDING_HTTP_POST, registry, config) validator.validate(request)
def test_logout_request_http_redirect_without_signature(self): # https://github.com/italia/spid-testenv2/issues/159 # https://github.com/italia/spid-testenv2/issues/165 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') request = FakeRequest(sample_requests.logout_no_signature % ('')) registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader([], [(0, 'http://localhost:3000/spid-sso')]) }) validator = SpidRequestValidator( 'logout', settings.BINDING_HTTP_REDIRECT, registry, config) validator.validate(request)
def test_missing_issuer(self): # https://github.com/italia/spid-testenv2/issues/133 config = FakeConfig('http://localhost:8088/sso') request = FakeRequest(sample_requests.missing_issuer) for binding in [ settings.BINDING_HTTP_POST, settings.BINDING_HTTP_REDIRECT ]: validator = SpidValidator('login', binding, {}, config) with pytest.raises(SPIDValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual('required key not provided', exc.details[0].message)
def test_unexpected_element(self): # See: https://github.com/italia/spid-testenv2/issues/79 validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) request = FakeRequest(sample_requests.unexpected_element) with pytest.raises(XMLSchemaValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertIn( "Element 'AuthnContextClassRef': " "This element is not expected. Expected is one of ( " "Conditions, RequestedAuthnContext, Scoping ).", exc.details[0].message)
def test_invalid_comparison_attribute(self): # https://github.com/italia/spid-testenv2/issues/97 validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) request = FakeRequest(sample_requests.invalid_comparison_attr) with pytest.raises(XMLSchemaValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual(exc.details[0].type_name, 'SCHEMAV_CVC_ENUMERATION_VALID') self.assertIn( "The value 'invalid' is not an element of the set " "{'exact', 'minimum', 'maximum', 'better'}", exc.details[0].message )
def test_blocking_validation_failure(self): xml = '<xml></xml>' blocking_validator = FailValidator( XMLFormatValidationError(['blocking error'])) nonblocking_validator = FailValidator( XMLSchemaValidationError(['nonblocking error'])) validators = [blocking_validator, nonblocking_validator] request = FakeRequest(xml) deserializer = HTTPRequestDeserializer( request, validators=validators, saml_class=FakeSAMLClass) with pytest.raises(DeserializationError) as excinfo: deserializer.deserialize() exc = excinfo.value self.assertEqual(len(exc.details), 1) self.assertEqual(exc.details[0], 'blocking error') self.assertEqual(exc.initial_data, xml)
def test_logout_request_http_post_without_signature(self): # https://github.com/italia/spid-testenv2/issues/159 # https://github.com/italia/spid-testenv2/issues/165 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') request = FakeRequest(sample_requests.logout_no_signature % ('')) registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader( [], [(0, 'http://localhost:3000/spid-sso')]) }) validator = SpidRequestValidator('logout', settings.BINDING_HTTP_POST, registry, config) with pytest.raises(SPIDValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual('LogoutRequest/Signature', exc.details[0].path) self.assertEqual('required key not provided', exc.details[0].message)
def test_nonblocking_validation_failure(self): xml = '<xml></xml>' first_nonblocking_validator = FailValidator( XMLSchemaValidationError(['a nonblocking error'])) second_nonblocking_validator = FailValidator( SPIDValidationError(['another nonblocking error'])) validators = [ first_nonblocking_validator, second_nonblocking_validator, ] request = FakeRequest(xml) deserializer = HTTPRequestDeserializer( request, validators=validators, saml_class=FakeSAMLClass) with pytest.raises(DeserializationError) as excinfo: deserializer.deserialize() exc = excinfo.value self.assertEqual(len(exc.details), 2) self.assertEqual(exc.details[0], 'a nonblocking error') self.assertEqual(exc.details[1], 'another nonblocking error') self.assertEqual(exc.initial_data, xml)
def test_authn_request_http_redirect_with_signature(self): # https://github.com/italia/spid-testenv2/issues/159 # https://github.com/italia/spid-testenv2/issues/165 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') request = FakeRequest(sample_requests.auth_no_signature % (sample_requests.fake_signature)) registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader([], [(0, 'http://localhost:3000/spid-sso')]) }) validator = SpidRequestValidator( 'login', settings.BINDING_HTTP_REDIRECT, registry, config) with pytest.raises(SPIDValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual( 'AuthnRequest/Signature', exc.details[0].path ) self.assertEqual('item not allowed', exc.details[0].message)
def test_authn_request_http_post_without_signature(self): # https://github.com/italia/spid-testenv2/issues/159 # https://github.com/italia/spid-testenv2/issues/165 config = FakeConfig('http://localhost:8088/sso', 'http://localhost:8088/') request = FakeRequest(sample_requests.auth_no_signature % ('')) registry = FakeRegistry({ 'https://localhost:8088/': ServiceProviderMetadataFakeLoader( [], [(0, 'http://localhost:3000/spid-sso')]) }) validator = SpidValidator('login', settings.BINDING_HTTP_POST, registry, config) with pytest.raises(SPIDValidationError) as excinfo: validator.validate(request) exc = excinfo.value self.assertEqual( 'xpath: {urn:oasis:names:tc:SAML:2.0:protocol}AuthnRequest/{http://www.w3.org/2000/09/xmldsig#}Signature', exc.details[0].path) self.assertEqual('required key not provided', exc.details[0].message)
def test_xml_with_declarations(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'<?xml version="1.0" encoding="utf-8" ?><a></a>') validator.validate(request)
def test_valid_request(self): validator = XMLFormatValidator(translator=FakeTranslator()) request = FakeRequest(b'<a></a>') self.assertIsNone(validator.validate(request))
def test_valid_requests(self): validator = AuthnRequestXMLSchemaValidator(translator=FakeTranslator()) for request in sample_requests.valid: request = FakeRequest(request) self.assertIsNone(validator.validate(request))