1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
from datetime import datetime
from unittest.mock import Mock
from unittest.mock import patch
from saml2.config import config_factory
from saml2.response import authn_response
from saml2.sigver import SignatureError
from dateutil import parser
from pytest import raises
from pathutils import dotname
from pathutils import full_path
SIGNED_XSW_ASSERTION_WRAPPER = full_path("xsw/signed-xsw-assertion-wrapper.xml")
SIGNED_XSW_ASSERTION_EXTENSIONS = full_path("xsw/signed-xsw-assertion-extensions.xml")
SIGNED_XSW_ASSERTION_ASSERTION = full_path("xsw/signed-xsw-assertion-assertion.xml")
SIGNED_ASSERTION_FIRST_SIG = full_path("xsw/signed-xsw-assertion-in-assertion-first-sig.xml")
SIGNED_REPONSE_FIRST_SIG = full_path("xsw/signed-xsw-response-in-response-first-sig.xml")
class TestXSW:
def setup_class(self):
self.conf = config_factory("sp", dotname("server_conf"))
self.ar = authn_response(self.conf, return_addrs="https://example.org/acs/post")
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_wrapper_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_WRAPPER) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_extensions_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_EXTENSIONS) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_xsw_assertion_assertion_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_XSW_ASSERTION_ASSERTION) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
class TestInvalidDepthFirstSig:
def setup_class(self):
self.conf = config_factory("sp", dotname("server_conf"))
self.ar = authn_response(self.conf, return_addrs="https://example.org/acs/post")
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_assertion_first_sig_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_ASSERTION_FIRST_SIG) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
self.ar.loads(xml_response, decode=False)
assert self.ar.came_from == 'http://localhost:8088/sso'
assert self.ar.session_id() == "id-abc"
assert self.ar.issuer() == 'urn:mace:example.com:saml:roland:idp'
with raises(SignatureError):
self.ar.verify()
assert self.ar.ava is None
assert self.ar.name_id is None
@patch('saml2.response.validate_on_or_after', return_value=True)
def test_signed_response_first_sig_should_fail(self, mock_validate_on_or_after):
self.ar.issue_instant_ok = Mock(return_value=True)
with open(SIGNED_REPONSE_FIRST_SIG) as fp:
xml_response = fp.read()
self.ar.outstanding_queries = {"id-abc": "http://localhost:8088/sso"}
self.ar.timeslack = 10000
with raises(SignatureError):
self.ar.loads(xml_response, decode=False)
|