|
1 | 1 | import copy |
| 2 | +import secrets |
2 | 3 | from unittest.mock import AsyncMock, MagicMock |
3 | 4 |
|
4 | 5 | import pytest |
| 6 | +from fastapi import HTTPException |
5 | 7 | from pytest_mock import MockerFixture |
6 | 8 |
|
7 | | -from murfey.server.api.auth import submit_to_auth_endpoint |
| 9 | +from murfey.server.api.auth import ( |
| 10 | + submit_to_auth_endpoint, |
| 11 | + validate_token, |
| 12 | +) |
8 | 13 |
|
9 | 14 |
|
10 | 15 | def test_check_user(): |
@@ -131,9 +136,95 @@ async def test_submit_to_auth_endpoint( |
131 | 136 | assert result == {"valid": (validation_outcome if status_code == 200 else False)} |
132 | 137 |
|
133 | 138 |
|
| 139 | +@pytest.mark.parametrize( |
| 140 | + "test_params", |
| 141 | + ( # Exception raised? | Auth URL | Auth type | Validation outcome | User decoded | User exists |
| 142 | + (False, "some_url", "cookie", True, True, True), |
| 143 | + (False, "", "password", True, True, True), |
| 144 | + # Auth endpoint returns False |
| 145 | + (True, "some_url", "cookie", False, True, True), |
| 146 | + # Authenticating with cookie, but no auth URL |
| 147 | + (True, "", "cookie", True, True, True), |
| 148 | + # Decoding fails |
| 149 | + (True, "", "password", True, False, True), |
| 150 | + # User check fails |
| 151 | + (True, "", "password", True, True, False), |
| 152 | + ), |
| 153 | +) |
134 | 154 | @pytest.mark.asyncio |
135 | | -async def test_validate_token(): |
136 | | - pass |
| 155 | +async def test_validate_token( |
| 156 | + mocker: MockerFixture, |
| 157 | + test_params: tuple[bool, str, str, bool, bool, bool], |
| 158 | +): |
| 159 | + # Unpack test params |
| 160 | + ( |
| 161 | + raises_exception, |
| 162 | + auth_url, |
| 163 | + auth_type, |
| 164 | + validation_outcome, |
| 165 | + user_decoded, |
| 166 | + user_exists, |
| 167 | + ) = test_params |
| 168 | + |
| 169 | + # Patch the auth URL to use |
| 170 | + mocker.patch("murfey.server.api.auth.auth_url", auth_url) |
| 171 | + |
| 172 | + # Create a mock token |
| 173 | + mock_token = "some_token" |
| 174 | + |
| 175 | + # Mock the request |
| 176 | + mock_request = MagicMock() |
| 177 | + |
| 178 | + # Mock the secret key and algorithms module-level variables |
| 179 | + mock_secret_key = mocker.patch( |
| 180 | + "murfey.server.api.auth.SECRET_KEY", secrets.token_hex(32) |
| 181 | + ) |
| 182 | + mock_algorithms = mocker.patch("murfey.server.api.auth.ALGORITHM", "HS256") |
| 183 | + |
| 184 | + # Mock the 'jwt.decode' function |
| 185 | + mock_decoded_data = {"user": "some_user"} if user_decoded else {} |
| 186 | + mock_decode = mocker.patch( |
| 187 | + "murfey.server.api.auth.jwt.decode", return_value=mock_decoded_data |
| 188 | + ) |
| 189 | + |
| 190 | + # Mock the 'check_user' function |
| 191 | + mock_check_user = mocker.patch( |
| 192 | + "murfey.server.api.auth.check_user", return_value=user_exists |
| 193 | + ) |
| 194 | + |
| 195 | + # Patch the security config |
| 196 | + mock_security_config = MagicMock() |
| 197 | + mock_security_config.auth_type = auth_type |
| 198 | + mocker.patch("murfey.server.api.auth.security_config", mock_security_config) |
| 199 | + |
| 200 | + # Patch the 'submit_to_auth_endpoint' function |
| 201 | + mock_submit = mocker.patch( |
| 202 | + "murfey.server.api.auth.submit_to_auth_endpoint", new_callable=AsyncMock |
| 203 | + ) |
| 204 | + mock_submit.return_value = {"valid": validation_outcome} |
| 205 | + |
| 206 | + # Run the function and check that the values passed and returned are as expected |
| 207 | + if not raises_exception: |
| 208 | + result = await validate_token( |
| 209 | + token=mock_token, |
| 210 | + request=mock_request, |
| 211 | + ) |
| 212 | + if auth_url: |
| 213 | + mock_submit.assert_called_once_with( |
| 214 | + "validate_token", mock_request, mock_token |
| 215 | + ) |
| 216 | + if auth_type == "password": |
| 217 | + mock_decode.assert_called_once_with( |
| 218 | + mock_token, mock_secret_key, algorithms=[mock_algorithms] |
| 219 | + ) |
| 220 | + mock_check_user.assert_called_once_with(mock_decoded_data["user"]) |
| 221 | + assert result is None |
| 222 | + else: |
| 223 | + with pytest.raises(HTTPException): |
| 224 | + await validate_token( |
| 225 | + token=mock_token, |
| 226 | + request=mock_request, |
| 227 | + ) |
137 | 228 |
|
138 | 229 |
|
139 | 230 | def test_validate_session_against_visit(): |
|
0 commit comments