|
1 | 1 | """
|
2 | 2 | Tests for the SAML frontend module src/backends/saml2.py.
|
3 | 3 | """
|
| 4 | +import os |
4 | 5 | import re
|
5 | 6 | from base64 import urlsafe_b64encode
|
6 |
| -from unittest.mock import Mock |
| 7 | +from collections import Counter |
| 8 | +from unittest.mock import Mock, patch |
7 | 9 | from urllib.parse import urlparse, parse_qs, parse_qsl
|
8 | 10 |
|
9 | 11 | import pytest
|
10 | 12 | from saml2 import BINDING_HTTP_REDIRECT
|
11 | 13 | from saml2.authn_context import PASSWORD
|
12 | 14 | from saml2.config import IdPConfig, SPConfig
|
| 15 | +from saml2.s_utils import deflate_and_base64_encode |
13 | 16 |
|
14 | 17 | from satosa.backends.saml2 import SAMLBackend
|
15 | 18 | from satosa.context import Context
|
16 | 19 | from satosa.internal_data import InternalRequest
|
17 | 20 | from tests.users import USERS
|
18 | 21 | from tests.util import FakeIdP, create_metadata_from_config_dict, FakeSP
|
19 | 22 |
|
| 23 | +TEST_RESOURCE_BASE_PATH = os.path.join(os.path.dirname(__file__), "../../test_resources") |
| 24 | + |
20 | 25 | INTERNAL_ATTRIBUTES = {
|
21 | 26 | 'attributes': {
|
22 | 27 | 'displayname': {'saml': ['displayName']},
|
@@ -182,6 +187,48 @@ def test_authn_response(self, context, idp_conf, sp_conf):
|
182 | 187 | self.assert_authn_response(internal_resp)
|
183 | 188 | assert self.samlbackend.name not in context.state
|
184 | 189 |
|
| 190 | + def test_authn_response_with_encrypted_assertion(self, sp_conf, context): |
| 191 | + with open(os.path.join(TEST_RESOURCE_BASE_PATH, |
| 192 | + "idp_metadata_for_encrypted_signed_auth_response.xml")) as idp_metadata_file: |
| 193 | + sp_conf["metadata"]["inline"] = [idp_metadata_file.read()] |
| 194 | + samlbackend = SAMLBackend(Mock(), INTERNAL_ATTRIBUTES, {"sp_config": sp_conf, |
| 195 | + "disco_srv": DISCOSRV_URL}, |
| 196 | + "base_url", "samlbackend") |
| 197 | + response_binding = BINDING_HTTP_REDIRECT |
| 198 | + relay_state = "test relay state" |
| 199 | + |
| 200 | + with open(os.path.join(TEST_RESOURCE_BASE_PATH, |
| 201 | + "auth_response_with_encrypted_signed_assertion.xml")) as auth_response_file: |
| 202 | + auth_response = auth_response_file.read() |
| 203 | + context.request = {"SAMLResponse": deflate_and_base64_encode(auth_response), "RelayState": relay_state} |
| 204 | + |
| 205 | + context.state[self.samlbackend.name] = {"relay_state": relay_state} |
| 206 | + with open(os.path.join(TEST_RESOURCE_BASE_PATH, "encryption_key.pem")) as encryption_key_file: |
| 207 | + samlbackend.encryption_keys = [encryption_key_file.read()] |
| 208 | + |
| 209 | + assertion_issued_at = 1479315212 |
| 210 | + with patch('saml2.validate.time_util.utc_now') as time_mock: |
| 211 | + time_mock.return_value = assertion_issued_at + 1 |
| 212 | + samlbackend.authn_response(context, response_binding) |
| 213 | + |
| 214 | + context, internal_resp = samlbackend.auth_callback_func.call_args[0] |
| 215 | + assert Counter(internal_resp.attributes.keys()) == Counter({"mail", "givenname", "displayname", "surname"}) |
| 216 | + |
| 217 | + def test_backend_reads_encryption_key_from_key_file(self, sp_conf): |
| 218 | + sp_conf["key_file"] = os.path.join(TEST_RESOURCE_BASE_PATH, "encryption_key.pem") |
| 219 | + samlbackend = SAMLBackend(Mock(), INTERNAL_ATTRIBUTES, {"sp_config": sp_conf, |
| 220 | + "disco_srv": DISCOSRV_URL}, |
| 221 | + "base_url", "samlbackend") |
| 222 | + assert samlbackend.encryption_keys |
| 223 | + |
| 224 | + def test_backend_reads_encryption_key_from_encryption_keypair(self, sp_conf): |
| 225 | + del sp_conf["key_file"] |
| 226 | + sp_conf["encryption_keypairs"] = [{"key_file": os.path.join(TEST_RESOURCE_BASE_PATH, "encryption_key.pem")}] |
| 227 | + samlbackend = SAMLBackend(Mock(), INTERNAL_ATTRIBUTES, {"sp_config": sp_conf, |
| 228 | + "disco_srv": DISCOSRV_URL}, |
| 229 | + "base_url", "samlbackend") |
| 230 | + assert samlbackend.encryption_keys |
| 231 | + |
185 | 232 | def test_metadata_endpoint(self, context, sp_conf):
|
186 | 233 | resp = self.samlbackend._metadata_endpoint(context)
|
187 | 234 | headers = dict(resp.headers)
|
|
0 commit comments