diff options
Diffstat (limited to 'tests/middleware/test_authenticate.py')
-rw-r--r-- | tests/middleware/test_authenticate.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/tests/middleware/test_authenticate.py b/tests/middleware/test_authenticate.py new file mode 100644 index 0000000..28ccef2 --- /dev/null +++ b/tests/middleware/test_authenticate.py @@ -0,0 +1,116 @@ +from base64 import b64encode +from wsgiref.validate import validator + +import pytest + +import paste +from paste import authenticate + +from ..common_wsgi import call_app + + +@pytest.fixture +def app(): + @validator + @authenticate + @validator + def app(_, start_response): + start_response("200 OK", [("Content-Type", "text/plain")]) + return [b"Hello, world!"] + + return app + + +@pytest.mark.parametrize("method", ["GET", "HEAD"]) +def test_unauthenticated_request(app, method, monkeypatch): + monkeypatch.delattr(paste, "check_token") + environ = {"REQUEST_METHOD": method} + response = call_app(app, environ) + assert response.data == b"Hello, world!" + assert response.status == "200 OK" + assert ("Content-Type", "text/plain") in response.headers + + +@pytest.mark.parametrize("method", ["GET", "HEAD"]) +def test_unauthenticated_request_with_key(app, method, monkeypatch): + monkeypatch.delattr(paste, "check_token") + environ = { + "REQUEST_METHOD": method, + "paste.db_conn": None, + "HTTP_AUTHORIZATION": "ApiKey AAAA", + } + response = call_app(app, environ) + assert response.data == b"Hello, world!" + assert response.status == "200 OK" + assert ("Content-Type", "text/plain") in response.headers + + +@pytest.mark.parametrize("method", ["POST", "PUT", "DELETE"]) +def test_authenticate_no_header(app, method, monkeypatch): + monkeypatch.delattr(paste, "check_token") + environ = {"REQUEST_METHOD": method} + response = call_app(app, environ) + assert response.data == b"401 Unauthorized\n" + assert response.status == "401 Unauthorized" + assert ("Content-Type", "text/plain") in response.headers + + +@pytest.mark.parametrize("method", ["POST", "PUT", "DELETE"]) +@pytest.mark.parametrize("key", ["ApiKey AAAA", "APIKey AAA", "APIKey AAAA", "AAAA"]) +def test_authenticate_malformed_key(app, method, key, monkeypatch): + monkeypatch.delattr(paste, "check_token") + environ = {"REQUEST_METHOD": method, "HTTP_AUTHORIZATION": key} + response = call_app(app, environ) + assert response.data == b"401 Unauthorized\n" + assert response.status == "401 Unauthorized" + assert ("Content-Type", "text/plain") in response.headers + + +@pytest.mark.parametrize("method", ["POST", "PUT", "DELETE"]) +def test_authenticate_check_token_fail(app, method, monkeypatch): + check_token_called = False + token = b"test" + environ = { + "REQUEST_METHOD": method, + "paste.db_conn": object(), + "HTTP_AUTHORIZATION": f"APIKey {b64encode(token).decode()}", + } + + def check_token(conn, tok): + nonlocal check_token_called + assert conn == environ["paste.db_conn"] + assert tok == token + check_token_called = True + return False + + monkeypatch.setattr(paste, "check_token", check_token) + response = call_app(app, environ) + assert check_token_called + assert response.data == b"401 Unauthorized\n" + assert response.status == "401 Unauthorized" + assert ("Content-Type", "text/plain") in response.headers + + +@pytest.mark.parametrize("method", ["POST", "PUT", "DELETE"]) +def test_authenticate_check_token_success(app, method, monkeypatch): + check_token_called = False + token = b"test" + environ = { + "REQUEST_METHOD": method, + "paste.db_conn": object(), + "HTTP_AUTHORIZATION": f"APIKey {b64encode(token).decode()}", + } + + def check_token(conn, tok): + nonlocal check_token_called + assert conn == environ["paste.db_conn"] + assert tok == token + check_token_called = True + return True + + monkeypatch.setattr(paste, "check_token", check_token) + response = call_app(app, environ) + assert check_token_called + assert response.data == b"Hello, world!" + assert response.status == "200 OK" + assert ("Content-Type", "text/plain") in response.headers |