From bd8a469e937cca1087fec8431ddc923842965285 Mon Sep 17 00:00:00 2001 From: dandds Date: Wed, 10 Jul 2019 11:07:24 -0400 Subject: [PATCH] Fix tests that were broken by a fixture CRL expiring. Adjust the broken tests to use our dynamic fixtures for PKI files. Some tests still rely on these fixtures, but this is a minimal patch to get the test suite passing again. Eventually all tests should use the pytest fixtures. --- tests/domain/authnid/test_crl.py | 29 +++++++++---- tests/fixtures/crl/client-ca.der.crl | Bin 502 -> 0 bytes tests/test_auth.py | 59 ++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 19 deletions(-) delete mode 100644 tests/fixtures/crl/client-ca.der.crl diff --git a/tests/domain/authnid/test_crl.py b/tests/domain/authnid/test_crl.py index fd088647..25a686cf 100644 --- a/tests/domain/authnid/test_crl.py +++ b/tests/domain/authnid/test_crl.py @@ -62,16 +62,27 @@ def test_can_build_crl_list_with_missing_crls(): assert len(cache.crl_cache.keys()) == 0 -def test_can_validate_certificate(): - cache = CRLCache( - "ssl/server-certs/ca-chain.pem", - crl_locations=["ssl/client-certs/client-ca.der.crl"], - ) - good_cert = open("ssl/client-certs/atat.mil.crt", "rb").read() - bad_cert = open("ssl/client-certs/bad-atat.mil.crt", "rb").read() - assert cache.crl_check(good_cert) +def test_crl_validation_on_login( + app, + client, + ca_key, + ca_file, + crl_file, + rsa_key, + make_x509, + make_crl, + serialize_pki_object_to_disk, +): + good_cert = make_x509(rsa_key(), signer_key=ca_key, cn="luke") + bad_cert = make_x509(rsa_key(), signer_key=ca_key, cn="darth") + + crl = make_crl(ca_key, expired_serials=[bad_cert.serial_number]) + serialize_pki_object_to_disk(crl, crl_file, encoding=Encoding.DER) + + cache = CRLCache(ca_file, crl_locations=[crl_file]) + assert cache.crl_check(good_cert.public_bytes(Encoding.PEM).decode()) with pytest.raises(CRLRevocationException): - cache.crl_check(bad_cert) + cache.crl_check(bad_cert.public_bytes(Encoding.PEM).decode()) def test_can_dynamically_update_crls( diff --git a/tests/fixtures/crl/client-ca.der.crl b/tests/fixtures/crl/client-ca.der.crl deleted file mode 100644 index 7eb07ee0499ca0c42c566bae1e73954921bd6a97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 502 zcmXqLV*F&#c-w%NjZ>@5qwPB{BO?ndgF$1jA-4f18*?ZNn=n&ou%W1dFo?q;%oC8B zmsebwQ){U=86 z^HXBwzemI+{}(-ODg1ZAC*95OZ%q)>dbet&Q^E0!jhou$C1pz;h<@3yQoHyLdmgVl zYXtk(v!^RJBrDgP_^Woa`^>>}T`Z*^+cbnN4#`eu)39JLt#$4Z=3g&$?l9AX_`Nxc zMdnQ0u()Ymh=I?huTCy(9p{#cuMFMyGVAcP{h~YLj+dPOHG7Sr*@=UHjwEibl)YAX zKYG@;me&fbUzV{N{WU9@%dE3Xq2WR*?>4cXs`6u|S9`Q4KYP8z=sNS3+)#a;nqEI8 w)ibJl-G06jDz7o+yRx$Hz_OxSD`NhrFMqb?$+LCuGd?G&xXGs(NHMek03YkOCIA2c diff --git a/tests/test_auth.py b/tests/test_auth.py index 6af412f4..cec65246 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -3,12 +3,15 @@ from urllib.parse import urlparse import pytest from datetime import datetime from flask import session, url_for +from cryptography.hazmat.primitives.serialization import Encoding + from .mocks import DOD_SDN_INFO, DOD_SDN, FIXTURE_EMAIL_ADDRESS from atst.domain.users import Users from atst.domain.permission_sets import PermissionSets from atst.domain.exceptions import NotFoundError from atst.domain.authnid.crl import CRLInvalidException from atst.domain.auth import UNPROTECTED_ROUTES +from atst.domain.authnid.crl import CRLCache from .factories import UserFactory @@ -131,24 +134,57 @@ def test_unprotected_routes_set_user_if_logged_in(client, app, user_session): assert user.full_name in resp.data.decode() -# this implicitly relies on the test config and test CRL in tests/fixtures/crl +@pytest.fixture +def swap_crl_cache( + app, ca_key, ca_file, crl_file, make_crl, serialize_pki_object_to_disk +): + original = app.crl_cache + + def _swap_crl_cache(new_cache=None): + if new_cache: + app.crl_cache = new_cache + else: + crl = make_crl(ca_key) + serialize_pki_object_to_disk(crl, crl_file, encoding=Encoding.DER) + app.crl_cache = CRLCache(ca_file, crl_locations=[crl_file]) + + yield _swap_crl_cache + + app.crl_cache = original -def test_crl_validation_on_login(client): - good_cert = open("ssl/client-certs/atat.mil.crt").read() - bad_cert = open("ssl/client-certs/bad-atat.mil.crt").read() +def test_crl_validation_on_login( + app, + client, + ca_key, + ca_file, + crl_file, + rsa_key, + make_x509, + make_crl, + serialize_pki_object_to_disk, + swap_crl_cache, +): + good_cert = make_x509(rsa_key(), signer_key=ca_key, cn="luke") + bad_cert = make_x509(rsa_key(), signer_key=ca_key, cn="darth") + + crl = make_crl(ca_key, expired_serials=[bad_cert.serial_number]) + serialize_pki_object_to_disk(crl, crl_file, encoding=Encoding.DER) + + cache = CRLCache(ca_file, crl_locations=[crl_file]) + swap_crl_cache(cache) # bad cert is on the test CRL - resp = _login(client, cert=bad_cert) + resp = _login(client, cert=bad_cert.public_bytes(Encoding.PEM).decode()) assert resp.status_code == 401 assert "user_id" not in session # good cert is not on the test CRL, passes - resp = _login(client, cert=good_cert) + resp = _login(client, cert=good_cert.public_bytes(Encoding.PEM).decode()) assert session["user_id"] -def test_creates_new_user_on_login(monkeypatch, client): +def test_creates_new_user_on_login(monkeypatch, client, ca_key): monkeypatch.setattr( "atst.domain.authnid.AuthenticationContext.authenticate", lambda *args: True ) @@ -166,14 +202,17 @@ def test_creates_new_user_on_login(monkeypatch, client): assert user.email == FIXTURE_EMAIL_ADDRESS -def test_creates_new_user_without_email_on_login(monkeypatch, client): - cert_file = open("ssl/client-certs/atat.mil.crt").read() +def test_creates_new_user_without_email_on_login( + client, ca_key, rsa_key, make_x509, swap_crl_cache +): + cert = make_x509(rsa_key(), signer_key=ca_key, cn=DOD_SDN) + swap_crl_cache() # ensure user does not exist with pytest.raises(NotFoundError): Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) - resp = _login(client, cert=cert_file) + resp = _login(client, cert=cert.public_bytes(Encoding.PEM).decode()) user = Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) assert user.first_name == DOD_SDN_INFO["first_name"]