Merge branch 'master' into ui/input-field-frontend-validation

This commit is contained in:
Patrick Smith
2018-08-12 12:16:46 -04:00
26 changed files with 549 additions and 96 deletions

View File

@@ -2,11 +2,19 @@ import os
import pytest
import alembic.config
import alembic.command
from logging.config import dictConfig
from atst.app import make_app, make_config
from atst.database import db as _db
import tests.factories as factories
dictConfig({
'version': 1,
'handlers': {'wsgi': {
'class': 'logging.NullHandler',
}}
})
@pytest.fixture(scope="session")
def app(request):

View File

@@ -0,0 +1,92 @@
import pytest
from atst.domain.authnid import AuthenticationContext
from atst.domain.exceptions import UnauthenticatedError, NotFoundError
from atst.domain.users import Users
from tests.mocks import DOD_SDN_INFO, DOD_SDN, FIXTURE_EMAIL_ADDRESS
from tests.factories import UserFactory
CERT = open("tests/fixtures/{}.crt".format(FIXTURE_EMAIL_ADDRESS)).read()
class MockCRLValidator():
def __init__(self, value):
self.value = value
def validate(self, cert):
return self.value
def test_can_authenticate():
auth_context = AuthenticationContext(
MockCRLValidator(True), "SUCCESS", DOD_SDN, CERT
)
assert auth_context.authenticate()
def test_unsuccessful_status():
auth_context = AuthenticationContext(
MockCRLValidator(True), "FAILURE", DOD_SDN, CERT
)
with pytest.raises(UnauthenticatedError) as excinfo:
assert auth_context.authenticate()
(message,) = excinfo.value.args
assert "client authentication" in message
def test_crl_check_fails():
auth_context = AuthenticationContext(
MockCRLValidator(False), "SUCCESS", DOD_SDN, CERT
)
with pytest.raises(UnauthenticatedError) as excinfo:
assert auth_context.authenticate()
(message,) = excinfo.value.args
assert "CRL check" in message
def test_bad_sdn():
auth_context = AuthenticationContext(
MockCRLValidator(True), "SUCCESS", "abc123", CERT
)
with pytest.raises(UnauthenticatedError) as excinfo:
auth_context.get_user()
(message,) = excinfo.value.args
assert "SDN" in message
def test_user_exists():
user = UserFactory.create(**DOD_SDN_INFO)
auth_context = AuthenticationContext(
MockCRLValidator(True), "SUCCESS", DOD_SDN, CERT
)
auth_user = auth_context.get_user()
assert auth_user == user
def test_creates_user():
# check user does not exist
with pytest.raises(NotFoundError):
Users.get_by_dod_id(DOD_SDN_INFO["dod_id"])
auth_context = AuthenticationContext(
MockCRLValidator(True), "SUCCESS", DOD_SDN, CERT
)
user = auth_context.get_user()
assert user.dod_id == DOD_SDN_INFO["dod_id"]
assert user.email == FIXTURE_EMAIL_ADDRESS
def test_user_cert_has_no_email():
cert = open("ssl/client-certs/atat.mil.crt").read()
auth_context = AuthenticationContext(
MockCRLValidator(True), "SUCCESS", DOD_SDN, cert
)
user = auth_context.get_user()
assert user.email == None

View File

@@ -4,7 +4,7 @@ import re
import os
import shutil
from OpenSSL import crypto, SSL
from atst.domain.authnid.crl.validator import Validator
from atst.domain.authnid.crl import Validator
import atst.domain.authnid.crl.util as util

View File

@@ -1,16 +1,39 @@
import pytest
import atst.domain.authnid.utils as utils
from tests.mocks import DOD_SDN
from tests.mocks import DOD_SDN, FIXTURE_EMAIL_ADDRESS
def test_parse_sdn():
parsed = utils.parse_sdn(DOD_SDN)
assert parsed.get('first_name') == 'ART'
assert parsed.get('last_name') == 'GARFUNKEL'
assert parsed.get('dod_id') == '5892460358'
assert parsed.get("first_name") == "ART"
assert parsed.get("last_name") == "GARFUNKEL"
assert parsed.get("dod_id") == "5892460358"
def test_parse_bad_sdn():
with pytest.raises(ValueError):
utils.parse_sdn('this has nothing to do with anything')
utils.parse_sdn("this has nothing to do with anything")
with pytest.raises(ValueError):
utils.parse_sdn(None)
def test_parse_email_cert():
cert_file = open("tests/fixtures/{}.crt".format(FIXTURE_EMAIL_ADDRESS), "rb").read()
email = utils.email_from_certificate(cert_file)
assert email == FIXTURE_EMAIL_ADDRESS
def test_parse_cert_with_no_email():
cert_file = open("tests/fixtures/no-email.crt", "rb").read()
with pytest.raises(ValueError) as excinfo:
email = utils.email_from_certificate(cert_file)
(message,) = excinfo.value.args
assert "email" in message
def test_parse_cert_with_no_san():
cert_file = open("tests/fixtures/no-san.crt", "rb").read()
with pytest.raises(ValueError) as excinfo:
email = utils.email_from_certificate(cert_file)
(message,) = excinfo.value.args
assert "subjectAltName" in message

46
tests/fixtures/README.md vendored Normal file
View File

@@ -0,0 +1,46 @@
# Regenerating Fixture Certificates
You don't need to keep the key file generated by this process.
1. Certificate with an email as subjectAltName:
```
openssl req -x509 \
-newkey rsa:4096 \
-sha256 \
-nodes \
-days 3650 \
-keyout _foo.key \
-out artgarfunkel@uso.mil.crt \
-subj "/CN=GARFUNKEL.ART.G.5892460358" \
-extensions SAN \
-config <(cat /etc/ssl/openssl.cnf; echo '[SAN]'; echo 'subjectAltName=email:artgarfunkel@uso.mil')
```
2. Certificate with a DNS name as subjectAltName:
```
openssl req -x509 \
-newkey rsa:4096 \
-sha256 \
-nodes \
-days 3650 \
-keyout _foo.key \
-out no-email.crt \
-subj "/CN=GARFUNKEL.ART.G.5892460358" \
-extensions SAN \
-config <(cat /etc/ssl/openssl.cnf; echo '[SAN]'; echo 'subjectAltName=DNS:artgarfunkel.com')
```
3. Certificate with no subjectAltName:
```
openssl req -x509 \
-newkey rsa:4096 \
-sha256 \
-nodes \
-days 3650 \
-keyout _foo.key \
-out no-san.crt \
-subj "/CN=GARFUNKEL.ART.G.5892460358"
```

29
tests/fixtures/artgarfunkel@uso.mil.crt vendored Normal file
View File

@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE8DCCAtigAwIBAgIJALTstfJQuulmMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV
BAMMGkdBUkZVTktFTC5BUlQuRy41ODkyNDYwMzU4MB4XDTE4MDgwODE0MDI0N1oX
DTI4MDgwNTE0MDI0N1owJTEjMCEGA1UEAwwaR0FSRlVOS0VMLkFSVC5HLjU4OTI0
NjAzNTgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQD1OuSSniuiUP3Q
JqVJOS2LE+kmK4Y5TexTCCDhBebarg+dEYipdA4AwZMKSDL/6D+lZJCM1MTsUgaN
X/8lRv2obVGnWuEL5Rbcwhlf3yTaohhlPk/qFyQoQaxcLZgwlwUn47i5jKG1cFqA
l4TignN3n6cwbpjFfkP9Oepiffu4ThrOsrOWTN56IB7TrHElFIdjVuUWbIuK9CET
8UWixUecrLr64AKyDndaVyzGJBwhtyn7AanVYld9la0FSxu8ZcYMikSOvOEqqOMA
Nu2NapInrb+g1JEPycXTpGxMiLbFscmAkgmAqkxzeFBW0UHCQsbxG6Ep1Km3QfYw
QqvEfNRPuGq2bGtpbMUF9K4DSsI2yErtc8QvKVQ86xEuwoiFxiRtO+WQKJrq8CqU
sZxcz6ZAw2pERIYtGCi573rxb8g7skEvlIPIYWqljEwFOIrgoRav0x3dHdfA5Ubh
M0fx38icinVmL0Xd7G0JFY2RFQ13/r/zaxmmm546tH9tSjn1bwaO/6OcX9g5kCUH
p2cWklug3/bDQyKre9UZBjI7bUMWtL1w6uhdRm5yq4lX+o8G/tbUYVPER75z+AKO
p/eizAKCKSHRXDKIJr3zZG54jyd+VzTcjBSNQN/liclEBzlnZqZUgPPUR8kQ0S3E
n8jQ/Jk9MS/DUuNvEzBgZS5e3KtpZwIDAQABoyMwITAfBgNVHREEGDAWgRRhcnRn
YXJmdW5rZWxAdXNvLm1pbDANBgkqhkiG9w0BAQsFAAOCAgEAQzAA7aweU7ZHDK3l
pjcpfXruVOqceGst/avMHZp3ZS9YOkd+K3jnLVBObfBGwZkJjsyqvs0AMVi3mTYY
WeEkhTk50G2xA2UydsOQcuH/qOT6duj54a0TCB4/2kMBq6IhCT3xR4rbfxA+5ArD
yCConiy1FUX5nofYGNC7VPUgjQb64LtTr1+wO6nTwdpALeOX2GZXoBWVQO2W+2Ul
buIGV5TnpjoJGJmuO/A76qwMi5+e6EYAKmomjGCaTKyvbb2WAlCoHzdDd+nQMFYm
gBBMVOkiTZ2udIbQMFGdqAZjDEP484rsCVrth4PKAZ9/3LAe6XddLZZbqq5cap2l
u6jDinFIeV2aldRh285qwvX7+R3KQK7k5wNDbf8DlaPUhnF+CliYDBKFCoKE60AY
mp40YME0NE3XSGuIemJUazxFAJ8zUu8yEP3K/mzAwtRHiy+yQwKyPK4Wl+skXYHs
XbouRkWK7jleVKXLiE0Uw0EbWkfAVBM8IgGWp70UivCTlAdokwdKBxsLhsn57mJ5
GP+9YTpwVQKWTBp06z0ZHaRI91d9Ke7YUSfDmLZ6VE9txqd9P2X2B2HbXFaYzGJh
gWtvqRh94ttaVsGr9iK7ANS9gXvn7Vb1ElyyF2wzP64WJtew7tywFq+Xhbm4/WPr
wM+BoGmfKP7uq0GBfu/HengJEGk=
-----END CERTIFICATE-----

29
tests/fixtures/no-email.crt vendored Normal file
View File

@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE6TCCAtGgAwIBAgIJAKlkkD2Xt+vWMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV
BAMMGkdBUkZVTktFTC5BUlQuRy41ODkyNDYwMzU4MB4XDTE4MDgwODE0MjI0MFoX
DTI4MDgwNTE0MjI0MFowJTEjMCEGA1UEAwwaR0FSRlVOS0VMLkFSVC5HLjU4OTI0
NjAzNTgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDi81dB+2WcfgoD
ls0A7q/lefu+rOEDp90o22MO/D4uAkqztI/O/JUzGs3MG6YWEREwanlgS67Cnhki
NFHWKh0QUXyqGqYgxmyNMXemawFI5ilpCXhToSoi3aKP8Da6YO1FbhF+X9NpEgpC
cNHwKnfzOreQ4s01q8TdKL6X9wQvtX1ILNjPpCRMrfaBkiD7VbAC+Ds8SW9V10MD
1jQkZyaPtZgNU9nou9OCwHpiva1HIckNy0E8UAuSGHWmwkK62rTUvZfKHrtWWaWY
G/njwSdotAZvH4xdFW+/wJdcpj1IHACtzkctLjub78RmuvPsNHcEy6x77efSJKvb
oBGvEzOFYqoXDhvLOpxQfsZNFO1suJlcXynzVx9hmVrUfw7l8Z/yUhuNKhuRQ7fw
+9YMuXrYrcTCsZx73eTsQCX7A6QSq5//N9GNSHl5/adZXcmSwFed6OOUrMRs73HY
IH35yiyGS4BbulyKUeGHdeiD00Crb2/DSxrH5M2BqFQw993clkhdbr8AT/B/lhh8
Bysc3fHxwXGN65k1vfgrMm3aULUHLDH9RWjMra8OF2dZndQfmFSIxVOmDmmVjfME
lBg1TXY+JyKdkZrMb8IOpd08F+g10s+OnImldjsoSW0qkxDzUIbDRSvPK5dxukDc
ygecXqeKB7Bm2lceAurcARZiDdGvRwIDAQABoxwwGjAYBgNVHREEETAPgg1nYXJm
dW5rZWwuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQCdaxkg4ZmmFqGqQ5bkjOucEowI
UpFIlgn3ORX/NjeAFpRlXr+kAyrezOfe3DzffFM63GVyqCR3swfwu0DdgpaGI++z
wMjXdDKDWfCSdFeFQczt/UyOQg7lkgKAgP6AgWrS9iOUwWY2Ecd+IhLjEAJ8ESgO
udi60tx9fDSlmpc3BlXBNkZUPGQW8abv+E2hV9dhNwCLVOxgK655E+9Lv3qRFFG5
HczGP8UcKL/0e1CIV8JfiPNG3lI9LJKE0fik7jN1nvPuM9ubKwKuxWgxDH4iP4aw
qa76rGYRT4VDcU89bRRX6fVCOK7iFd4db32zsAaFcOnztpMWAyIaTSZ4RuJivpqn
rTl0+ZOVHLierhFAH96prWcUBtyaprRCx5y/bIme+KBdEuge+s6+H4fYjMeryenQ
6kK8yqqAngDxxD400U1uP5TERu+E/JiP1AaiyPyh5j1bOjzM8/aohwTLK4pSeUHC
2AITpHPjXumTYMVLJliJ1/B+ZW8wS7kg1ICL6x9hrt/SbdDqQPZa/pE8NHuzMNSr
TaTDjaBEz50awlMYv4b3u+YQbVhGabw+2sYDG6VhiMakyuY2FCIi5Tc/ybBvXta8
lh8Xo8hSVlwvPumqLLITl17+KXHNL1KnTgWfXntFL6t/2OQrSbDfVXmThtW+FEmm
7ZFG54OsGWYdg8uNNg==
-----END CERTIFICATE-----

31
tests/fixtures/no-san.crt vendored Normal file
View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFVTCCAz2gAwIBAgIJAJRtzRX0VhJJMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV
BAMTGkdBUkZVTktFTC5BUlQuRy41ODkyNDYwMzU4MB4XDTE4MDgwODE0MjQ1NFoX
DTI4MDgwNTE0MjQ1NFowJTEjMCEGA1UEAxMaR0FSRlVOS0VMLkFSVC5HLjU4OTI0
NjAzNTgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCak8upRyMLNUKK
vP6Ly50KGXDAktTBOFHDDsTRIIBeEiRImcuQ3nrqgHPKxlYdPG1k88VSDnrCDZry
DTm58NGCrtB6tJPqlZag8vpNffk9pEPOBKvUN9v5xqGgSN3sIdv0aMtMRJUXS61R
gzKJ76D+QM/7sKFhtPmETcfkBN99On7Zxw33TcwIlpv8t8tPB6F/r8jw07oWFBza
Z1Ui2+mFs6rZlxFOP8qRo82iencrMuW3/Tvqjl0N/AHPkdT7PbqAyg1aDkHYIBvc
euk/23Rgp1BQCX/Dia412/mMW0l6wYrw3pMBQ0j9LPSKTWx6rf7xa5TTweqcoKhB
zaeOV90wQk7gd+13u12ZqtPDI2Lgzi9PiIIDyDOGe4yX+O4YGTOV1pX2RyYCx9Hi
D6Pz9LoABz7TYq7A+LjKx5T5Q4XXiyUiQHTHQ5dC8v1rcUdZBB47eyAE0ZtVcCVI
tcG6eJgbM907AAabwca5sy0ogfYABMSUz6YWA1SMeDclwtRBlSWMFa2OCDJl7wBU
5Iyj/5a4MJ834IJh++gxpeijTktU1RyCDRUgXlAQNdqFxPmgwPbTo4KPDOw/YUnt
PSZfO2jiqhXgSRxlG5+2CAMiUVo2kelJxemDkJ30Yk3ebjx6qyEYizE0Mmh3xFYf
cOr7h1dxhjvAUtu3/ekNZWdz4WUcMQIDAQABo4GHMIGEMB0GA1UdDgQWBBRGIuCr
zBlH956853iOtEt/RF1wkzBVBgNVHSMETjBMgBRGIuCrzBlH956853iOtEt/RF1w
k6EppCcwJTEjMCEGA1UEAxMaR0FSRlVOS0VMLkFSVC5HLjU4OTI0NjAzNTiCCQCU
bc0V9FYSSTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAHVurBIQJS
makSWkuIFYuhKI5GDU9R1xeFe56zDVKE6Xoqki6CxUlHcIY/QN2nJ02GVN12GMAi
p4jewaiomr0LIlmzk63jn380okRjOFNoieIyQiXL0rH2oV4DESbWLuLoFnWFHGI7
8VsyURDe00H58t3MsEEOzrbjSV7KeyifjIND6yrDuzoLY2FquTOq3Q41XRJxIOuk
0p0Cd9E07YzAb9kzODO5ZPvXfkAIqZIrAYb9bjcMs6gb8CbzA/STdSEPp2NjgAsc
fjI0VtUPyTX2fKE9nrHeSNsT7WFPslbzvXVtlmUvlyDgnHglKjsgSLTgFaAERUSz
WkJG0+lysAPga/qpD22C3OB/igT/S+KJjw8oubX6iAAxIDM1Oa+YStft5IXX2KSm
5FT2HIMtXBG9pkgmJ9O+xrDrJwSz+sezXYuV88T4fDYdXAUqgBudmml/h+OGEB4C
k3Mc0ibe5Np4SyDg9qWDa+u6GojQCkTA0ygxcXR0M/t204MXqV7g4zCt624BB+nH
TYLeq49SQsl2XmPLsjwWIToly1F6tizP0gWYFamGD2bqZNDIEl/5a/CLwpOlSWc8
K6tfqAlNnM56/vMXDeo/na7XLRHPkLisUZCxBYVuSFu77gZsawVxcZlO3Hwn1L7a
Pdu9qr067Y/6AAogCQANMXWfywkc+TZMlQ==
-----END CERTIFICATE-----

View File

@@ -3,18 +3,11 @@ from tests.factories import RequestFactory, UserFactory
MOCK_USER = UserFactory.build()
MOCK_REQUEST = RequestFactory.build(
creator=MOCK_USER.id,
body={
"financial_verification": {
"pe_id": "0203752A",
},
}
creator=MOCK_USER.id, body={"financial_verification": {"pe_id": "0203752A"}}
)
DOD_SDN_INFO = {
'first_name': 'ART',
'last_name': 'GARFUNKEL',
'dod_id': '5892460358'
}
DOD_SDN_INFO = {"first_name": "ART", "last_name": "GARFUNKEL", "dod_id": "5892460358"}
DOD_SDN = f"CN={DOD_SDN_INFO['last_name']}.{DOD_SDN_INFO['first_name']}.G.{DOD_SDN_INFO['dod_id']},OU=OTHER,OU=PKI,OU=DoD,O=U.S. Government,C=US"
MOCK_VALID_PE_ID = "8675309U"
FIXTURE_EMAIL_ADDRESS = "artgarfunkel@uso.mil"

View File

@@ -66,3 +66,39 @@ def test_nonexistent_request(client, user_session):
response = client.get("/requests/new/1/foo", follow_redirects=True)
assert response.status_code == 404
def test_creator_info_is_autopopulated(monkeypatch, client, user_session):
user = UserFactory.create()
user_session(user)
request = RequestFactory.create(creator=user, body={"information_about_you": {}})
response = client.get("/requests/new/2/{}".format(request.id))
body = response.data.decode()
assert 'value="{}"'.format(user.first_name) in body
assert 'value="{}"'.format(user.last_name) in body
assert 'value="{}"'.format(user.email) in body
def test_creator_info_is_autopopulated_for_new_request(monkeypatch, client, user_session):
user = UserFactory.create()
user_session(user)
response = client.get("/requests/new/2")
body = response.data.decode()
assert 'value="{}"'.format(user.first_name) in body
assert 'value="{}"'.format(user.last_name) in body
assert 'value="{}"'.format(user.email) in body
def test_non_creator_info_is_not_autopopulated(monkeypatch, client, user_session):
user = UserFactory.create()
creator = UserFactory.create()
user_session(user)
request = RequestFactory.create(creator=creator, body={"information_about_you": {}})
response = client.get("/requests/new/2/{}".format(request.id))
body = response.data.decode()
assert not user.first_name in body
assert not user.last_name in body
assert not user.email in body

View File

@@ -1,6 +1,7 @@
import pytest
from tests.mocks import MOCK_USER
from tests.factories import RequestFactory
from atst.models.request_status_event import RequestStatus
def _mock_func(*args, **kwargs):
@@ -27,12 +28,11 @@ def test_submit_autoapproved_reviewed_request(monkeypatch, client, user_session)
user_session()
monkeypatch.setattr("atst.domain.requests.Requests.get", _mock_func)
monkeypatch.setattr("atst.domain.requests.Requests.submit", _mock_func)
monkeypatch.setattr("atst.models.request.Request.status", "approved")
# this just needs to send a known invalid form value
monkeypatch.setattr("atst.models.request.Request.status", RequestStatus.PENDING_FINANCIAL_VERIFICATION)
response = client.post(
"/requests/submit/1",
headers={"Content-Type": "application/x-www-form-urlencoded"},
data="",
follow_redirects=False,
)
assert "/requests?modal=True" in response.headers["Location"]
assert "/requests?modal=" in response.headers["Location"]

View File

@@ -1,5 +1,9 @@
import pytest
from flask import session, url_for
from .mocks import DOD_SDN
from .mocks import DOD_SDN_INFO, DOD_SDN, FIXTURE_EMAIL_ADDRESS
from atst.domain.users import Users
from atst.domain.exceptions import NotFoundError
from .factories import UserFactory
MOCK_USER = {"id": "438567dd-25fa-4d83-a8cc-8aa8366cb24a"}
@@ -10,12 +14,15 @@ def _fetch_user_info(c, t):
def test_successful_login_redirect(client, monkeypatch):
monkeypatch.setattr("atst.routes._is_valid_certificate", lambda *args: True)
monkeypatch.setattr("atst.domain.authnid.AuthenticationContext.authenticate", lambda *args: True)
monkeypatch.setattr("atst.domain.authnid.AuthenticationContext.get_user", lambda *args: UserFactory.create())
resp = client.get(
"/login-redirect",
environ_base={
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS",
"HTTP_X_SSL_CLIENT_S_DN": "",
"HTTP_X_SSL_CLIENT_CERT": "",
},
)
@@ -58,8 +65,8 @@ UNPROTECTED_ROUTES = ["/", "/login-dev", "/login-redirect", "/unauthorized"]
def test_crl_validation_on_login(client):
good_cert = open("ssl/client-certs/atat.mil.crt", "rb").read()
bad_cert = open("ssl/client-certs/bad-atat.mil.crt", "rb").read()
good_cert = open("ssl/client-certs/atat.mil.crt").read()
bad_cert = open("ssl/client-certs/bad-atat.mil.crt").read()
# bad cert is on the test CRL
resp = client.get(
@@ -67,7 +74,7 @@ def test_crl_validation_on_login(client):
environ_base={
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS",
"HTTP_X_SSL_CLIENT_S_DN": DOD_SDN,
"HTTP_X_SSL_CLIENT_CERT": bad_cert.decode(),
"HTTP_X_SSL_CLIENT_CERT": bad_cert,
},
)
assert resp.status_code == 401
@@ -79,9 +86,55 @@ def test_crl_validation_on_login(client):
environ_base={
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS",
"HTTP_X_SSL_CLIENT_S_DN": DOD_SDN,
"HTTP_X_SSL_CLIENT_CERT": good_cert.decode(),
"HTTP_X_SSL_CLIENT_CERT": good_cert,
},
)
assert resp.status_code == 302
assert "home" in resp.headers["Location"]
assert session["user_id"]
def test_creates_new_user_on_login(monkeypatch, client):
monkeypatch.setattr("atst.domain.authnid.AuthenticationContext.authenticate", lambda *args: True)
cert_file = open("tests/fixtures/{}.crt".format(FIXTURE_EMAIL_ADDRESS)).read()
# ensure user does not exist
with pytest.raises(NotFoundError):
Users.get_by_dod_id(DOD_SDN_INFO["dod_id"])
resp = client.get(
"/login-redirect",
environ_base={
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS",
"HTTP_X_SSL_CLIENT_S_DN": DOD_SDN,
"HTTP_X_SSL_CLIENT_CERT": cert_file,
},
)
user = Users.get_by_dod_id(DOD_SDN_INFO["dod_id"])
assert user.first_name == DOD_SDN_INFO["first_name"]
assert user.last_name == DOD_SDN_INFO["last_name"]
assert user.email == FIXTURE_EMAIL_ADDRESS
def test_creates_new_user_without_email_on_login(monkeypatch, client):
monkeypatch.setattr("atst.routes._is_valid_certificate", lambda *args: True)
cert_file = open("ssl/client-certs/atat.mil.crt").read()
# ensure user does not exist
with pytest.raises(NotFoundError):
Users.get_by_dod_id(DOD_SDN_INFO["dod_id"])
resp = client.get(
"/login-redirect",
environ_base={
"HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS",
"HTTP_X_SSL_CLIENT_S_DN": DOD_SDN,
"HTTP_X_SSL_CLIENT_CERT": cert_file,
},
)
user = Users.get_by_dod_id(DOD_SDN_INFO["dod_id"])
assert user.first_name == DOD_SDN_INFO["first_name"]
assert user.last_name == DOD_SDN_INFO["last_name"]
assert user.email == None