summaryrefslogtreecommitdiff
path: root/tests/test_xsw.py
blob: 62d57cd3b63d803c334a12e7cb24deb2521c667b (plain)
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
from datetime import datetime
from unittest.mock import Mock
from unittest.mock import patch

from dateutil import parser
from pathutils import dotname
from pathutils import full_path
from pytest import raises

from saml2.config import config_factory
from saml2.response import authn_response
from saml2.sigver import SignatureError


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)