From 3cf20586c2371f27d35a8a258d31d9f95fcb9c40 Mon Sep 17 00:00:00 2001 From: "David D. Riddle" Date: Thu, 13 Nov 2025 12:58:59 -0600 Subject: [PATCH 01/20] Update to use latest vcr-py cleaner Closes #29 --- requirements-test.txt | 87 +++++++++++++++++++++---------------------- tests/conftest.py | 8 ++-- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/requirements-test.txt b/requirements-test.txt index f3f5927..d325cd8 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,70 +1,67 @@ -argcomplete==3.6.2 +argcomplete==3.6.3 asttokens==3.0.0 autopep8==2.3.2 -certifi==2025.4.26 +certifi==2025.11.12 cfgv==3.4.0 -charset-normalizer==3.4.2 -coverage==7.8.2 +charset-normalizer==3.4.4 +coverage==7.11.3 decorator==5.2.1 detect-secrets==1.5.0 -distlib==0.3.9 -exceptiongroup==1.3.0 -executing==2.2.0 -filelock==3.18.0 -flake8==7.2.0 -identify==2.6.12 -idna==3.10 -importlib_metadata==8.7.0 -iniconfig==2.1.0 +distlib==0.4.0 +executing==2.2.1 +filelock==3.20.0 +flake8==7.3.0 +identify==2.6.15 +idna==3.11 +iniconfig==2.3.0 ipdb==0.13.13 -ipython==8.18.1 +ipython==9.7.0 +ipython_pygments_lexers==1.1.1 jedi==0.19.2 -matplotlib-inline==0.1.7 +matplotlib-inline==0.2.1 mccabe==0.7.0 -multidict==6.4.4 -mypy==1.16.0 +multidict==6.7.0 +mypy==1.18.2 mypy_extensions==1.1.0 nodeenv==1.9.1 packaging==25.0 -parso==0.8.4 +parso==0.8.5 pathspec==0.12.1 pexpect==4.9.0 -platformdirs==4.3.8 +platformdirs==4.5.0 pluggy==1.6.0 -pre_commit==4.2.0 -prompt_toolkit==3.0.51 -propcache==0.3.2 +pre_commit==4.4.0 +prompt_toolkit==3.0.52 +propcache==0.4.1 ptyprocess==0.7.0 pure_eval==0.2.3 -pycodestyle==2.13.0 -pyflakes==3.3.2 -Pygments==2.19.1 +pycodestyle==2.14.0 +pyflakes==3.4.0 +Pygments==2.19.2 PyJWT==2.10.1 -pytest==8.4.0 -PyYAML==6.0.2 -requests==2.32.4 -setuptools-scm==8.3.1 +pytest==9.0.1 +PyYAML==6.0.3 +requests==2.32.5 +setuptools-scm==9.2.2 stack-data==0.6.3 -tomli==2.2.1 tomlkit==0.13.3 traitlets==5.14.3 -types-PyMySQL==1.1.0.20250516 -types-python-dateutil==2.9.0.20250516 -types-pytz==2025.2.0.20250516 -types-PyYAML==6.0.12.20250516 +types-PyMySQL==1.1.0.20250916 +types-python-dateutil==2.9.0.20251108 +types-pytz==2025.2.0.20251108 +types-PyYAML==6.0.12.20250915 types-requests==2.31.0.6 -types-setuptools==80.9.0.20250529 -types-simplejson==3.20.0.20250326 -types-six==1.17.0.20250515 +types-setuptools==80.9.0.20250822 +types-simplejson==3.20.0.20250822 +types-six==1.17.0.20251009 types-urllib3==1.26.25.14 -typing_extensions==4.14.0 +typing_extensions==4.15.0 urllib3==1.26.19 -vcr_cleaner @ git+https://github.com/techservicesillinois/vcrpy-cleaner.git@82bd9745642e81b2f794781aec89676540fab5cc +vcr_cleaner @ git+https://github.com/techservicesillinois/vcrpy-cleaner.git@be2bf6e0b8e4eda9416d3131611306084377009d vcrpy==7.0.0 -virtualenv==20.31.2 -wcwidth==0.2.13 -wrapt==1.17.2 -xmltodict==0.14.2 -yarl==1.20.1 +virtualenv==20.35.4 +wcwidth==0.2.14 +wrapt==2.0.1 +xmltodict==1.0.2 +yarl==1.22.0 yq==3.4.3 -zipp==3.23.0 diff --git a/tests/conftest.py b/tests/conftest.py index 617bc56..042d175 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,8 @@ from clearpass.client import APIConnection -from vcr_cleaner import CleanYAMLSerializer, clean_if +from vcr_cleaner import CleanYAMLSerializer +from vcr_cleaner.filters import if_uri_endswith CASSETTE_USERNAME = "JOE" @@ -15,7 +16,6 @@ CASSETTE_ENDPOINT = "notauri.edu" CASSETTE_CLIENT_ID = "FAKEID" CASSETTE_CLIENT_SECRET = "NOTASECRET" # pragma: allowlist secret -URL = f"https://{CASSETTE_ENDPOINT}" CLEANER_SALT = 'salty' CLEANER_JWT_TOKEN = {'exp': datetime.datetime(2049, 6, 25)} @@ -57,7 +57,6 @@ def clean_cookie(request: dict, response: dict): response['headers']['Set-Cookie'] = 'NO-COOKIE-FOR-YOU' -@clean_if(uri=f"{URL}/api/oauth") def clean_token(request: dict, response: dict): '''Clean a JSON token.''' token = {'access_token': 'NOTASECRET'} @@ -102,9 +101,8 @@ def cassette(request) -> vcr.cassette.Cassette: yaml_cleaner = CleanYAMLSerializer() my_vcr.register_serializer("cleanyaml", yaml_cleaner) - # TODO: Register cleaner functions here: yaml_cleaner.register_cleaner(clean_uri) - yaml_cleaner.register_cleaner(clean_token) + yaml_cleaner.register_cleaner(if_uri_endswith("/api/oauth", clean_token)) yaml_cleaner.register_cleaner(clean_cookie) with my_vcr.use_cassette(f'{request.function.__name__}.yaml', From b453097bb55b43447d1ebd3d635fb78f16800dce Mon Sep 17 00:00:00 2001 From: "David D. Riddle" Date: Thu, 13 Nov 2025 13:19:58 -0600 Subject: [PATCH 02/20] FIXUP --- .github/workflows/tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7678fec..3e4a214 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,8 @@ jobs: - uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v5 + with: + python-version: '3.10' - name: Linting run: | make lint @@ -30,4 +32,4 @@ jobs: - name: Run unit tests run: | - make unit \ No newline at end of file + make unit From e072900b1340c6469e557f4b98ebf351ffcddd86 Mon Sep 17 00:00:00 2001 From: Zach Carrington Date: Thu, 13 Nov 2025 15:59:34 -0600 Subject: [PATCH 03/20] fixup --- cassettes/test_404_disable_mac.yaml | 16 ++++-- cassettes/test_404_enable_mac.yaml | 16 ++++-- cassettes/test_connectivity.yaml | 13 +++-- cassettes/test_disable_mac.yaml | 33 ++++++++---- cassettes/test_enable_mac.yaml | 32 ++++++++---- cassettes/test_get_info_for_mac_address.yaml | 55 ++++++++++++++------ tests/conftest.py | 15 +++++- tests/test_connector.py | 2 + 8 files changed, 131 insertions(+), 51 deletions(-) diff --git a/cassettes/test_404_disable_mac.yaml b/cassettes/test_404_disable_mac.yaml index 30a3f2a..9ce5361 100644 --- a/cassettes/test_404_disable_mac.yaml +++ b/cassettes/test_404_disable_mac.yaml @@ -14,7 +14,7 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 05 Aug 2024 16:40:43 GMT + - Thu, 13 Nov 2025 21:34:16 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -44,8 +44,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -61,7 +65,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/endpoint/mac-address/deadbeef1234 response: @@ -78,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 16:40:43 GMT + - Thu, 13 Nov 2025 21:34:16 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -92,8 +96,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 404 message: Not Found diff --git a/cassettes/test_404_enable_mac.yaml b/cassettes/test_404_enable_mac.yaml index 4ea1f5c..5d9ee81 100644 --- a/cassettes/test_404_enable_mac.yaml +++ b/cassettes/test_404_enable_mac.yaml @@ -14,7 +14,7 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 05 Aug 2024 16:40:44 GMT + - Thu, 13 Nov 2025 21:34:17 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -44,8 +44,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -61,7 +65,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/endpoint/mac-address/deadbeef1234 response: @@ -78,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 16:40:44 GMT + - Thu, 13 Nov 2025 21:34:17 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -92,8 +96,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 404 message: Not Found diff --git a/cassettes/test_connectivity.yaml b/cassettes/test_connectivity.yaml index 0178a47..f17ff86 100644 --- a/cassettes/test_connectivity.yaml +++ b/cassettes/test_connectivity.yaml @@ -14,12 +14,12 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: body: - string: '{"access_token": "CLEANED"}' + string: '{"access_token": "NOTASECRET"}' headers: Cache-Control: - no-store @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 22 Jul 2024 20:38:25 GMT + - Thu, 13 Nov 2025 21:34:14 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -39,14 +39,17 @@ interactions: - no-cache Server: - Apache - Set-Cookie: - - GSID=3cabr753nknijgm1unpfbv7eqk; path=/; secure; HttpOnly; SameSite=Lax + Set-Cookie: NO-COOKIE-FOR-YOU Vary: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK diff --git a/cassettes/test_disable_mac.yaml b/cassettes/test_disable_mac.yaml index 8b7eefe..201354d 100644 --- a/cassettes/test_disable_mac.yaml +++ b/cassettes/test_disable_mac.yaml @@ -14,7 +14,7 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 05 Aug 2024 16:31:44 GMT + - Thu, 13 Nov 2025 21:34:15 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -44,8 +44,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -61,24 +65,25 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/endpoint/mac-address/123123123123 response: body: - string: '{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Aug 05, 2024 11:27:32 CDT","_stuff":"deleted"}' + string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled + By":"zdc","Disabled Reason":"testing"},"added_at":"Nov 15, 2023 14:52:34 CST","updated_at":"Nov + 06, 2024 12:03:57 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate Connection: - Keep-Alive Content-Length: - - '267' + - '317' Content-Type: - application/hal+json Date: - - Mon, 05 Aug 2024 16:31:45 GMT + - Thu, 13 Nov 2025 21:34:15 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -92,8 +97,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -114,14 +123,14 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: PUT uri: https://notauri.edu/api/endpoint/4524 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Aug 05, 2024 11:31:45 CDT","stuff":"deleted"}' + 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:15 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -132,7 +141,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 05 Aug 2024 16:31:45 GMT + - Thu, 13 Nov 2025 21:34:15 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -146,8 +155,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK diff --git a/cassettes/test_enable_mac.yaml b/cassettes/test_enable_mac.yaml index 686eea1..d0bbf5b 100644 --- a/cassettes/test_enable_mac.yaml +++ b/cassettes/test_enable_mac.yaml @@ -14,7 +14,7 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 05 Aug 2024 16:27:31 GMT + - Thu, 13 Nov 2025 21:34:16 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -44,8 +44,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -61,25 +65,25 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/endpoint/mac-address/123123123123 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled - By":"automation","Disabled Reason":"Disabled"},"added_at":"Nov 15, 2023 14:52:34 - CST","updated_at":"Mar 28, 2024 15:31:54 CDT","stuff":"deleted"}' + By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 + 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:15 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate Connection: - Keep-Alive Content-Length: - - '325' + - '330' Content-Type: - application/hal+json Date: - - Mon, 05 Aug 2024 16:27:31 GMT + - Thu, 13 Nov 2025 21:34:16 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -93,8 +97,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -114,13 +122,13 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: PUT uri: https://notauri.edu/api/endpoint/4524 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Aug 05, 2024 11:27:32 CDT","stuff":"deleted"}' + 15, 2023 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:17 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -131,7 +139,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 05 Aug 2024 16:27:32 GMT + - Thu, 13 Nov 2025 21:34:17 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -145,8 +153,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK diff --git a/cassettes/test_get_info_for_mac_address.yaml b/cassettes/test_get_info_for_mac_address.yaml index bd2dbef..d35447a 100644 --- a/cassettes/test_get_info_for_mac_address.yaml +++ b/cassettes/test_get_info_for_mac_address.yaml @@ -14,7 +14,7 @@ interactions: Content-Type: - application/json User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: POST uri: https://notauri.edu/api/oauth response: @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 05 Aug 2024 19:44:09 GMT + - Thu, 13 Nov 2025 21:34:17 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -44,8 +44,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -61,25 +65,24 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/endpoint?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D response: body: - string: '{"_embedded":{"items":[{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled - By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Aug 05, 2024 11:31:45 CDT","_links":{"self":{"stuff":"cleaned"}}}]}}' + string: '{"_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"},"first":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"}},"_embedded":{"items":[{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov + 15, 2023 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:17 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}]}}' headers: Cache-Control: - no-store, no-cache, must-revalidate Connection: - Keep-Alive Content-Length: - - '766' + - '703' Content-Type: - application/hal+json Date: - - Mon, 05 Aug 2024 19:44:09 GMT + - Thu, 13 Nov 2025 21:34:18 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -93,8 +96,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 200 message: OK @@ -110,7 +117,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/device?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D response: @@ -127,7 +134,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 19:44:10 GMT + - Thu, 13 Nov 2025 21:34:18 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -141,8 +148,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 403 message: Forbidden @@ -158,7 +169,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/guest?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D response: @@ -175,7 +186,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 19:44:10 GMT + - Thu, 13 Nov 2025 21:34:18 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -189,8 +200,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 403 message: Forbidden @@ -206,7 +221,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/session?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D response: @@ -223,7 +238,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 19:44:10 GMT + - Thu, 13 Nov 2025 21:34:18 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -237,8 +252,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 403 message: Forbidden @@ -254,7 +273,7 @@ interactions: Connection: - keep-alive User-Agent: - - python-requests/2.32.3 + - python-requests/2.32.5 method: GET uri: https://notauri.edu/api/insight/endpoint/mac/123123123123 response: @@ -271,7 +290,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 05 Aug 2024 19:44:10 GMT + - Thu, 13 Nov 2025 21:34:18 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -285,8 +304,12 @@ interactions: - X-Forwarded-For X-Content-Type-Options: - nosniff + - nosniff + X-Frame-Options: + - SAMEORIGIN X-XSS-Protection: - 1;mode=block + - 1;mode=block status: code: 404 message: Not Found diff --git a/tests/conftest.py b/tests/conftest.py index 042d175..4d6f4bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,12 +4,14 @@ import pytest import vcr +import logging from clearpass.client import APIConnection - from vcr_cleaner import CleanYAMLSerializer from vcr_cleaner.filters import if_uri_endswith +# Set up logger +logger = logging.getLogger(__name__) CASSETTE_USERNAME = "JOE" CASSETTE_PASSWORD = "NOTAPASSWORD" # pragma: allowlist secret @@ -59,7 +61,16 @@ def clean_cookie(request: dict, response: dict): def clean_token(request: dict, response: dict): '''Clean a JSON token.''' - token = {'access_token': 'NOTASECRET'} + secret = "NOTASECRET" + try: + token = json.loads(response['body']['string']) + if 'access_token' not in token: + logger.warning(f"No access_token in token response: {token}") + secret = "ERROR: ACCESS TOKEN NOT FOUND" + except json.JSONDecodeError: + logger.warning(f"Token response is not valid JSON: {token}") + secret = "ERROR: ACCESS TOKEN NOT FOUND: INVALID JSON" + token = {'access_token': secret} response['body']['string'] = json.dumps(token) diff --git a/tests/test_connector.py b/tests/test_connector.py index df76dc8..215ff32 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -8,6 +8,8 @@ def test_connectivity(cassette, clearpass_client): def test_failed_connectivity(cassette, clearpass_client): result = clearpass_client.test_connectivity() + # This cassette is handcrafted. Expect a failure if you use valid + # credentials. Expect to lock yourself out if you use invalid credentials. assert result is False From 89fc1eb9847415232deb6bdace230023a1b4bacf Mon Sep 17 00:00:00 2001 From: Zach Carrington Date: Thu, 13 Nov 2025 16:02:08 -0600 Subject: [PATCH 04/20] Fixup --- tests/conftest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 4d6f4bc..ce7e30d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -61,16 +61,16 @@ def clean_cookie(request: dict, response: dict): def clean_token(request: dict, response: dict): '''Clean a JSON token.''' - secret = "NOTASECRET" + message = "NOTASECRET" try: token = json.loads(response['body']['string']) if 'access_token' not in token: logger.warning(f"No access_token in token response: {token}") - secret = "ERROR: ACCESS TOKEN NOT FOUND" + message = "ERROR: ACCESS TOKEN NOT FOUND" except json.JSONDecodeError: logger.warning(f"Token response is not valid JSON: {token}") - secret = "ERROR: ACCESS TOKEN NOT FOUND: INVALID JSON" - token = {'access_token': secret} + message = "ERROR: ACCESS TOKEN NOT FOUND: INVALID JSON" + token = {'access_token': message} response['body']['string'] = json.dumps(token) From 2ea7279f5b76c4a43640c1377a5bbb97f0ad664f Mon Sep 17 00:00:00 2001 From: Zach Carrington Date: Thu, 13 Nov 2025 16:07:20 -0600 Subject: [PATCH 05/20] fixup --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e4a214..d447acc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,8 +20,8 @@ jobs: - uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v5 - with: - python-version: '3.10' + with: + python-version: '3.10' - name: Linting run: | make lint From 5c7a6d654498cced68ee4e8f4ba5cd217b799869 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 10:31:24 -0600 Subject: [PATCH 06/20] Fix for CI/CD - no longer pin versions with requirements.txt --- .github/workflows/tests.yml | 2 -- Makefile | 29 ++-------------- requirements-test.txt | 67 ------------------------------------- 3 files changed, 3 insertions(+), 95 deletions(-) delete mode 100644 requirements-test.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d447acc..6ef560f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,8 +20,6 @@ jobs: - uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v5 - with: - python-version: '3.10' - name: Linting run: | make lint diff --git a/Makefile b/Makefile index 9d39bab..c0cfb38 100644 --- a/Makefile +++ b/Makefile @@ -1,36 +1,14 @@ VENV_PYTHON:=venv/bin/python -VENV_REQS:=.requirements.venv SRCS:=$(shell find src tests -name '*.py') all: test -# BSD `sed` treats the `-i` option differently than Linux and others. -# Check for Mac OS X 'Darwin' and set our `-i` option accordingly. -ifeq ($(UNAME), Darwin) -# macOS (BSD sed) - SED_INPLACE := -i '' -else -# Linux and others (GNU sed) - SED_INPLACE := -i -endif - -venv: requirements-test.txt +venv: requirements-test.in rm -rf $@ python -m venv venv - $(VENV_PYTHON) -m pip install -r requirements-test.txt + $(VENV_PYTHON) -m pip install -r $^ # Install dependencies from pyproject.toml $(VENV_PYTHON) -m pip install -e . - - -requirements-test.txt: export VCR_CLEANER_REPO=git+https://github.com/techservicesillinois/vcrpy-cleaner.git -requirements-test.txt: requirements-test.in - rm -rf $(VENV_REQS) - python -m venv $(VENV_REQS) - # Workaround for wheel install failures. - $(VENV_REQS)/bin/python -m pip install --upgrade pip - $(VENV_REQS)/bin/python -m pip install -r $^ - $(VENV_REQS)/bin/python -m pip freeze -qqq > $@ - sed $(SED_INPLACE) "s;^vcr-cleaner==.*;$(VCR_CLEANER_REPO);" $@ lint: venv .lint .lint: $(SRCS) $(TSCS) @@ -53,10 +31,9 @@ unit: venv test: lint static unit clean: - rm -rf venv $(VENV_REQS) rm -rf .lint .static rm -rf .mypy_cache -find src -type d -name __pycache__ -exec rm -fr "{}" \; force-clean: clean - rm -f requirements-test.txt \ No newline at end of file + rm -rf venv diff --git a/requirements-test.txt b/requirements-test.txt deleted file mode 100644 index d325cd8..0000000 --- a/requirements-test.txt +++ /dev/null @@ -1,67 +0,0 @@ -argcomplete==3.6.3 -asttokens==3.0.0 -autopep8==2.3.2 -certifi==2025.11.12 -cfgv==3.4.0 -charset-normalizer==3.4.4 -coverage==7.11.3 -decorator==5.2.1 -detect-secrets==1.5.0 -distlib==0.4.0 -executing==2.2.1 -filelock==3.20.0 -flake8==7.3.0 -identify==2.6.15 -idna==3.11 -iniconfig==2.3.0 -ipdb==0.13.13 -ipython==9.7.0 -ipython_pygments_lexers==1.1.1 -jedi==0.19.2 -matplotlib-inline==0.2.1 -mccabe==0.7.0 -multidict==6.7.0 -mypy==1.18.2 -mypy_extensions==1.1.0 -nodeenv==1.9.1 -packaging==25.0 -parso==0.8.5 -pathspec==0.12.1 -pexpect==4.9.0 -platformdirs==4.5.0 -pluggy==1.6.0 -pre_commit==4.4.0 -prompt_toolkit==3.0.52 -propcache==0.4.1 -ptyprocess==0.7.0 -pure_eval==0.2.3 -pycodestyle==2.14.0 -pyflakes==3.4.0 -Pygments==2.19.2 -PyJWT==2.10.1 -pytest==9.0.1 -PyYAML==6.0.3 -requests==2.32.5 -setuptools-scm==9.2.2 -stack-data==0.6.3 -tomlkit==0.13.3 -traitlets==5.14.3 -types-PyMySQL==1.1.0.20250916 -types-python-dateutil==2.9.0.20251108 -types-pytz==2025.2.0.20251108 -types-PyYAML==6.0.12.20250915 -types-requests==2.31.0.6 -types-setuptools==80.9.0.20250822 -types-simplejson==3.20.0.20250822 -types-six==1.17.0.20251009 -types-urllib3==1.26.25.14 -typing_extensions==4.15.0 -urllib3==1.26.19 -vcr_cleaner @ git+https://github.com/techservicesillinois/vcrpy-cleaner.git@be2bf6e0b8e4eda9416d3131611306084377009d -vcrpy==7.0.0 -virtualenv==20.35.4 -wcwidth==0.2.14 -wrapt==2.0.1 -xmltodict==1.0.2 -yarl==1.22.0 -yq==3.4.3 From 8ec4c4621030ff1246d9ceb3e227fd3f4d4ba855 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 10:32:55 -0600 Subject: [PATCH 07/20] Cleanup - should not need work-around now --- requirements-test.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements-test.in b/requirements-test.in index 8773007..7824dd9 100644 --- a/requirements-test.in +++ b/requirements-test.in @@ -23,5 +23,3 @@ setuptools-scm vcrpy git+https://github.com/techservicesillinois/vcrpy-cleaner.git yq -# Requirements are also here because pyproject.toml and pip are dumb -requests From cb3d23600aaf679fbe1507004ef7ab50f455228a Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 11:58:34 -0600 Subject: [PATCH 08/20] WIP - Generic URL cleaner --- tests/conftest.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index ce7e30d..cc17857 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,7 @@ import pytest import vcr import logging +import re from clearpass.client import APIConnection from vcr_cleaner import CleanYAMLSerializer @@ -93,13 +94,47 @@ def remove_creds(request): def clean_uri(request: dict, response: dict): + '''Clean the URI''' if "uri" not in request.keys(): return request + # TODO: Let's not use the environment for this. request['uri'] = request['uri'].replace( os.environ.get("CLEARPASS_ENDPOINT"), CASSETTE_ENDPOINT) return request +def clean_request_response_urls(request: dict, response: dict): + '''Replace anything that looks like a URL in the request or response.''' + # TODO: Update this to get the whole request...then remove clean_uri above + # request['body'] = _clean_dict_urls(request['body']) + # response['body'] = _clean_dict_urls(response['body']) + + request = _clean_dict_urls(request) + + # TODO: Move this update and clear into the _clean_dict_urls below + updated = clean_dict_urls(request) + request.clear() + request.update(updated) + + updated = clean_dict_urls(response) + response.clear() + response.update(updated) + + +def _clean_dict_urls(message: dict): + json_dump = json.dumps(message) + re_rule = r'[^\s"\'<>/]+' + # Oh my, they look like this: https:\\\\/\\\\/etc.etc.illinois.edu + + # HTTPS + cleaned = re.sub( + r"\.illinois\.edu", '.example.edu', json_dump) + + # breakpoint() + + return json.loads(cleaned) + + @pytest.fixture def cassette(request) -> vcr.cassette.Cassette: my_vcr = vcr.VCR( @@ -113,6 +148,7 @@ def cassette(request) -> vcr.cassette.Cassette: yaml_cleaner = CleanYAMLSerializer() my_vcr.register_serializer("cleanyaml", yaml_cleaner) yaml_cleaner.register_cleaner(clean_uri) + yaml_cleaner.register_cleaner(clean_request_response_urls) yaml_cleaner.register_cleaner(if_uri_endswith("/api/oauth", clean_token)) yaml_cleaner.register_cleaner(clean_cookie) From d8ddb21f749444107d34eb57f501fb21c0415b41 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 14:33:28 -0600 Subject: [PATCH 09/20] WIP - URL cleaner recipe --- tests/conftest.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index cc17857..68e75d1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -109,14 +109,12 @@ def clean_request_response_urls(request: dict, response: dict): # request['body'] = _clean_dict_urls(request['body']) # response['body'] = _clean_dict_urls(response['body']) - request = _clean_dict_urls(request) - # TODO: Move this update and clear into the _clean_dict_urls below - updated = clean_dict_urls(request) + updated = _clean_dict_urls(request) request.clear() request.update(updated) - updated = clean_dict_urls(response) + updated = _clean_dict_urls(response) response.clear() response.update(updated) @@ -128,7 +126,7 @@ def _clean_dict_urls(message: dict): # HTTPS cleaned = re.sub( - r"\.illinois\.edu", '.example.edu', json_dump) + r"/[^/]+\.illinois\.edu", '/cleaned.example.edu', json_dump) # breakpoint() From 6e57b3a76532ae71ef9d939e6bb0feaf36658893 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 14:35:26 -0600 Subject: [PATCH 10/20] WIP - Simplify --- tests/conftest.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 68e75d1..3484b5d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -110,27 +110,19 @@ def clean_request_response_urls(request: dict, response: dict): # response['body'] = _clean_dict_urls(response['body']) # TODO: Move this update and clear into the _clean_dict_urls below - updated = _clean_dict_urls(request) - request.clear() - request.update(updated) - - updated = _clean_dict_urls(response) - response.clear() - response.update(updated) + _clean_dict_urls(request) + _clean_dict_urls(response) def _clean_dict_urls(message: dict): - json_dump = json.dumps(message) - re_rule = r'[^\s"\'<>/]+' - # Oh my, they look like this: https:\\\\/\\\\/etc.etc.illinois.edu - # HTTPS + json_dump = json.dumps(message) cleaned = re.sub( r"/[^/]+\.illinois\.edu", '/cleaned.example.edu', json_dump) - # breakpoint() - - return json.loads(cleaned) + # Update the original dict + message.clear() + message.update(json.loads(cleaned)) @pytest.fixture From 60b88005158f5707c0c80064f11eacf1b16eead0 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 14:38:47 -0600 Subject: [PATCH 11/20] WIP - Regenerated --- cassettes/test_disable_mac.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cassettes/test_disable_mac.yaml b/cassettes/test_disable_mac.yaml index 201354d..f57f312 100644 --- a/cassettes/test_disable_mac.yaml +++ b/cassettes/test_disable_mac.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:15 GMT + - Mon, 17 Nov 2025 20:38:27 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -67,23 +67,23 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/endpoint/mac-address/123123123123 + uri: https://cleaned.example.edu/api/endpoint/mac-address/123123123123 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled - By":"zdc","Disabled Reason":"testing"},"added_at":"Nov 15, 2023 14:52:34 CST","updated_at":"Nov - 06, 2024 12:03:57 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' + By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 + 14:52:34 CST","updated_at":"Nov 17, 2025 14:35:47 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate Connection: - Keep-Alive Content-Length: - - '317' + - '330' Content-Type: - application/hal+json Date: - - Thu, 13 Nov 2025 21:34:15 GMT + - Mon, 17 Nov 2025 20:38:28 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -125,12 +125,12 @@ interactions: User-Agent: - python-requests/2.32.5 method: PUT - uri: https://notauri.edu/api/endpoint/4524 + uri: https://cleaned.example.edu/api/endpoint/4524 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:15 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 14:38:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -141,7 +141,7 @@ interactions: Content-Type: - application/hal+json Date: - - Thu, 13 Nov 2025 21:34:15 GMT + - Mon, 17 Nov 2025 20:38:28 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: From 244ec9b82c25b94a25192df029d62e041363a7fc Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 14:39:04 -0600 Subject: [PATCH 12/20] FIXUP - simplify --- tests/conftest.py | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 3484b5d..8008dce 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -93,32 +93,16 @@ def remove_creds(request): return request -def clean_uri(request: dict, response: dict): - '''Clean the URI''' - if "uri" not in request.keys(): - return request - # TODO: Let's not use the environment for this. - request['uri'] = request['uri'].replace( - os.environ.get("CLEARPASS_ENDPOINT"), CASSETTE_ENDPOINT) - return request - - -def clean_request_response_urls(request: dict, response: dict): +def clean_urls(request: dict, response: dict): '''Replace anything that looks like a URL in the request or response.''' - # TODO: Update this to get the whole request...then remove clean_uri above - # request['body'] = _clean_dict_urls(request['body']) - # response['body'] = _clean_dict_urls(response['body']) - - # TODO: Move this update and clear into the _clean_dict_urls below _clean_dict_urls(request) _clean_dict_urls(response) def _clean_dict_urls(message: dict): - json_dump = json.dumps(message) - cleaned = re.sub( - r"/[^/]+\.illinois\.edu", '/cleaned.example.edu', json_dump) + cleaned = re.sub(r"/[^/]+\.illinois\.edu", + '/cleaned.example.edu', json.dumps(message)) # Update the original dict message.clear() @@ -137,8 +121,7 @@ def cassette(request) -> vcr.cassette.Cassette: yaml_cleaner = CleanYAMLSerializer() my_vcr.register_serializer("cleanyaml", yaml_cleaner) - yaml_cleaner.register_cleaner(clean_uri) - yaml_cleaner.register_cleaner(clean_request_response_urls) + yaml_cleaner.register_cleaner(clean_urls) yaml_cleaner.register_cleaner(if_uri_endswith("/api/oauth", clean_token)) yaml_cleaner.register_cleaner(clean_cookie) From 3e8d4a97f1c7a2060781275d9df0722d1c52d989 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 15:00:57 -0600 Subject: [PATCH 13/20] WIP - Nicer clean_domain function --- tests/conftest.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8008dce..d5d62d4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -93,21 +93,29 @@ def remove_creds(request): return request -def clean_urls(request: dict, response: dict): - '''Replace anything that looks like a URL in the request or response.''' - _clean_dict_urls(request) - _clean_dict_urls(response) - +def _clean_dict_hostnames(message: dict, rule: str, replacement: str): + '''Update the dictionary with rule matches replaced.''' -def _clean_dict_urls(message: dict): - - cleaned = re.sub(r"/[^/]+\.illinois\.edu", - '/cleaned.example.edu', json.dumps(message)) + cleaned = re.sub(rule, replacement, json.dumps(message)) # Update the original dict message.clear() message.update(json.loads(cleaned)) +def clean_domains(domain: str, replacement: str='cleaned.example.edu'): + '''Replace anything that looks like the given domain.''' + + rule = f"/[^/]+{ domain.replace('.', '\.') }" + rep = f"/{ replacement }" + + def wrapper(request: dict, response: dict): + _clean_dict_hostnames(request, rule, rep) + _clean_dict_hostnames(response, rule, rep) + + wrapper.__doc__ = clean_domains.__doc__ + + return wrapper + @pytest.fixture def cassette(request) -> vcr.cassette.Cassette: @@ -121,7 +129,7 @@ def cassette(request) -> vcr.cassette.Cassette: yaml_cleaner = CleanYAMLSerializer() my_vcr.register_serializer("cleanyaml", yaml_cleaner) - yaml_cleaner.register_cleaner(clean_urls) + yaml_cleaner.register_cleaner(clean_domains('illinois.edu')) yaml_cleaner.register_cleaner(if_uri_endswith("/api/oauth", clean_token)) yaml_cleaner.register_cleaner(clean_cookie) From e8269d6f6d837332a20c81de8c3779fa9bfc0f8c Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 15:03:54 -0600 Subject: [PATCH 14/20] Update cassettes with clean_domain --- cassettes/test_404_disable_mac.yaml | 8 +++--- cassettes/test_404_enable_mac.yaml | 8 +++--- cassettes/test_connectivity.yaml | 4 +-- cassettes/test_disable_mac.yaml | 10 +++---- cassettes/test_enable_mac.yaml | 16 +++++------ cassettes/test_get_info_for_mac_address.yaml | 28 ++++++++++---------- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/cassettes/test_404_disable_mac.yaml b/cassettes/test_404_disable_mac.yaml index 9ce5361..8af9006 100644 --- a/cassettes/test_404_disable_mac.yaml +++ b/cassettes/test_404_disable_mac.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:16 GMT + - Mon, 17 Nov 2025 21:02:27 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -67,7 +67,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/endpoint/mac-address/deadbeef1234 + uri: https://cleaned.example.edu/api/endpoint/mac-address/deadbeef1234 response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Not @@ -82,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:16 GMT + - Mon, 17 Nov 2025 21:02:28 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_404_enable_mac.yaml b/cassettes/test_404_enable_mac.yaml index 5d9ee81..06e22f1 100644 --- a/cassettes/test_404_enable_mac.yaml +++ b/cassettes/test_404_enable_mac.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:17 GMT + - Mon, 17 Nov 2025 21:02:30 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -67,7 +67,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/endpoint/mac-address/deadbeef1234 + uri: https://cleaned.example.edu/api/endpoint/mac-address/deadbeef1234 response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Not @@ -82,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:17 GMT + - Mon, 17 Nov 2025 21:02:30 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_connectivity.yaml b/cassettes/test_connectivity.yaml index f17ff86..f08280c 100644 --- a/cassettes/test_connectivity.yaml +++ b/cassettes/test_connectivity.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:14 GMT + - Mon, 17 Nov 2025 21:02:24 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_disable_mac.yaml b/cassettes/test_disable_mac.yaml index f57f312..8783046 100644 --- a/cassettes/test_disable_mac.yaml +++ b/cassettes/test_disable_mac.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 20:38:27 GMT + - Mon, 17 Nov 2025 21:02:25 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -72,7 +72,7 @@ interactions: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 17, 2025 14:35:47 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 15:00:19 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -83,7 +83,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 20:38:28 GMT + - Mon, 17 Nov 2025 21:02:26 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -130,7 +130,7 @@ interactions: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 17, 2025 14:38:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:27 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -141,7 +141,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 20:38:28 GMT + - Mon, 17 Nov 2025 21:02:27 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_enable_mac.yaml b/cassettes/test_enable_mac.yaml index d0bbf5b..e578cdc 100644 --- a/cassettes/test_enable_mac.yaml +++ b/cassettes/test_enable_mac.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:16 GMT + - Mon, 17 Nov 2025 21:02:28 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -67,12 +67,12 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/endpoint/mac-address/123123123123 + uri: https://cleaned.example.edu/api/endpoint/mac-address/123123123123 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:15 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:27 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -83,7 +83,7 @@ interactions: Content-Type: - application/hal+json Date: - - Thu, 13 Nov 2025 21:34:16 GMT + - Mon, 17 Nov 2025 21:02:29 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -124,11 +124,11 @@ interactions: User-Agent: - python-requests/2.32.5 method: PUT - uri: https://notauri.edu/api/endpoint/4524 + uri: https://cleaned.example.edu/api/endpoint/4524 response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:17 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}' + 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -139,7 +139,7 @@ interactions: Content-Type: - application/hal+json Date: - - Thu, 13 Nov 2025 21:34:17 GMT + - Mon, 17 Nov 2025 21:02:29 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_get_info_for_mac_address.yaml b/cassettes/test_get_info_for_mac_address.yaml index d35447a..3c68b4f 100644 --- a/cassettes/test_get_info_for_mac_address.yaml +++ b/cassettes/test_get_info_for_mac_address.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"access_token": "NOTASECRET"}' @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Thu, 13 Nov 2025 21:34:17 GMT + - Mon, 17 Nov 2025 21:02:31 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -67,11 +67,11 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/endpoint?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D + uri: https://cleaned.example.edu/api/endpoint?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D response: body: - string: '{"_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"},"first":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"}},"_embedded":{"items":[{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Nov 13, 2025 15:34:17 CST","_links":{"self":{"href":"https:\/\/cplab.techservices.illinois.edu\/api\/endpoint\/4524"}}}]}}' + string: '{"_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"},"first":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"}},"_embedded":{"items":[{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov + 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}]}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -82,7 +82,7 @@ interactions: Content-Type: - application/hal+json Date: - - Thu, 13 Nov 2025 21:34:18 GMT + - Mon, 17 Nov 2025 21:02:31 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -119,7 +119,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/device?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D + uri: https://cleaned.example.edu/api/device?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Forbidden","status":403,"detail":"Access @@ -134,7 +134,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:18 GMT + - Mon, 17 Nov 2025 21:02:32 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -171,7 +171,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/guest?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D + uri: https://cleaned.example.edu/api/guest?filter=%7B%22mac%22%3A%20%2212-31-23-12-31-23%22%7D response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Forbidden","status":403,"detail":"Access @@ -186,7 +186,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:18 GMT + - Mon, 17 Nov 2025 21:02:32 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -223,7 +223,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/session?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D + uri: https://cleaned.example.edu/api/session?filter=%7B%22mac_address%22%3A%20%22123123123123%22%7D response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Forbidden","status":403,"detail":"Access @@ -238,7 +238,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:18 GMT + - Mon, 17 Nov 2025 21:02:33 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -275,7 +275,7 @@ interactions: User-Agent: - python-requests/2.32.5 method: GET - uri: https://notauri.edu/api/insight/endpoint/mac/123123123123 + uri: https://cleaned.example.edu/api/insight/endpoint/mac/123123123123 response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Not @@ -290,7 +290,7 @@ interactions: Content-Type: - application/problem+json Date: - - Thu, 13 Nov 2025 21:34:18 GMT + - Mon, 17 Nov 2025 21:02:33 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: From 6a070ece365edb4c0d31fc7e8f7853825e7fd708 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 15:56:46 -0600 Subject: [PATCH 15/20] Update to use clean_domains from vcrpy cleaner --- tests/conftest.py | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d5d62d4..d35bbf8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,6 +10,7 @@ from clearpass.client import APIConnection from vcr_cleaner import CleanYAMLSerializer from vcr_cleaner.filters import if_uri_endswith +from vcr_cleaner.cleaners import clean_domains # Set up logger logger = logging.getLogger(__name__) @@ -93,30 +94,6 @@ def remove_creds(request): return request -def _clean_dict_hostnames(message: dict, rule: str, replacement: str): - '''Update the dictionary with rule matches replaced.''' - - cleaned = re.sub(rule, replacement, json.dumps(message)) - - # Update the original dict - message.clear() - message.update(json.loads(cleaned)) - -def clean_domains(domain: str, replacement: str='cleaned.example.edu'): - '''Replace anything that looks like the given domain.''' - - rule = f"/[^/]+{ domain.replace('.', '\.') }" - rep = f"/{ replacement }" - - def wrapper(request: dict, response: dict): - _clean_dict_hostnames(request, rule, rep) - _clean_dict_hostnames(response, rule, rep) - - wrapper.__doc__ = clean_domains.__doc__ - - return wrapper - - @pytest.fixture def cassette(request) -> vcr.cassette.Cassette: my_vcr = vcr.VCR( From 40ad0cbbc0f1e5fb584ed8d907898cbd54cad93d Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 15:59:08 -0600 Subject: [PATCH 16/20] Fixup --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index d35bbf8..48968be 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,7 +5,6 @@ import pytest import vcr import logging -import re from clearpass.client import APIConnection from vcr_cleaner import CleanYAMLSerializer From 44d25638ea47533aede431309e8521a380867ed0 Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 17 Nov 2025 16:05:26 -0600 Subject: [PATCH 17/20] Regenerate cassettes with clean_domains --- cassettes/test_404_disable_mac.yaml | 4 ++-- cassettes/test_404_enable_mac.yaml | 4 ++-- cassettes/test_connectivity.yaml | 2 +- cassettes/test_disable_mac.yaml | 15 +++++++-------- cassettes/test_enable_mac.yaml | 10 +++++----- cassettes/test_get_info_for_mac_address.yaml | 14 +++++++------- tests/conftest.py | 2 +- 7 files changed, 25 insertions(+), 26 deletions(-) diff --git a/cassettes/test_404_disable_mac.yaml b/cassettes/test_404_disable_mac.yaml index 8af9006..15848a1 100644 --- a/cassettes/test_404_disable_mac.yaml +++ b/cassettes/test_404_disable_mac.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:27 GMT + - Mon, 17 Nov 2025 22:02:31 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -82,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:28 GMT + - Mon, 17 Nov 2025 22:02:31 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_404_enable_mac.yaml b/cassettes/test_404_enable_mac.yaml index 06e22f1..c545c36 100644 --- a/cassettes/test_404_enable_mac.yaml +++ b/cassettes/test_404_enable_mac.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:30 GMT + - Mon, 17 Nov 2025 22:02:33 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -82,7 +82,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:30 GMT + - Mon, 17 Nov 2025 22:02:34 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_connectivity.yaml b/cassettes/test_connectivity.yaml index f08280c..bf2cf93 100644 --- a/cassettes/test_connectivity.yaml +++ b/cassettes/test_connectivity.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:24 GMT + - Mon, 17 Nov 2025 22:02:28 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_disable_mac.yaml b/cassettes/test_disable_mac.yaml index 8783046..0776e75 100644 --- a/cassettes/test_disable_mac.yaml +++ b/cassettes/test_disable_mac.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:25 GMT + - Mon, 17 Nov 2025 22:02:29 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -70,20 +70,19 @@ interactions: uri: https://cleaned.example.edu/api/endpoint/mac-address/123123123123 response: body: - string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled - By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 17, 2025 15:00:19 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + string: '{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov + 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate Connection: - Keep-Alive Content-Length: - - '330' + - '267' Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 21:02:26 GMT + - Mon, 17 Nov 2025 22:02:30 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -130,7 +129,7 @@ interactions: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:27 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 16:02:30 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -141,7 +140,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 21:02:27 GMT + - Mon, 17 Nov 2025 22:02:30 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_enable_mac.yaml b/cassettes/test_enable_mac.yaml index e578cdc..a336e37 100644 --- a/cassettes/test_enable_mac.yaml +++ b/cassettes/test_enable_mac.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:28 GMT + - Mon, 17 Nov 2025 22:02:32 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -72,7 +72,7 @@ interactions: body: string: '{"id":4524,"mac_address":"123123123123","status":"Disabled","randomized_mac":true,"attributes":{"Disabled By":"TESTING","Disabled Reason":"Still testing..."},"added_at":"Nov 15, 2023 - 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:27 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + 14:52:34 CST","updated_at":"Nov 17, 2025 16:02:30 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -83,7 +83,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 21:02:29 GMT + - Mon, 17 Nov 2025 22:02:32 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -128,7 +128,7 @@ interactions: response: body: string: '{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' + 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 16:02:33 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -139,7 +139,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 21:02:29 GMT + - Mon, 17 Nov 2025 22:02:33 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/cassettes/test_get_info_for_mac_address.yaml b/cassettes/test_get_info_for_mac_address.yaml index 3c68b4f..9b9ee49 100644 --- a/cassettes/test_get_info_for_mac_address.yaml +++ b/cassettes/test_get_info_for_mac_address.yaml @@ -30,7 +30,7 @@ interactions: Content-Type: - application/json Date: - - Mon, 17 Nov 2025 21:02:31 GMT + - Mon, 17 Nov 2025 22:02:34 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -71,7 +71,7 @@ interactions: response: body: string: '{"_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"},"first":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint?calculate_count=false\u0026offset=0\u0026limit=25\u0026sort=%2Bid\u0026filter=%7B%22mac_address%22%3A+%22123123123123%22%7D"}},"_embedded":{"items":[{"id":4524,"mac_address":"123123123123","status":"Known","randomized_mac":true,"attributes":{},"added_at":"Nov - 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 15:02:29 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}]}}' + 15, 2023 14:52:34 CST","updated_at":"Nov 17, 2025 16:02:33 CST","_links":{"self":{"href":"https:\/\/cleaned.example.edu\/api\/endpoint\/4524"}}}]}}' headers: Cache-Control: - no-store, no-cache, must-revalidate @@ -82,7 +82,7 @@ interactions: Content-Type: - application/hal+json Date: - - Mon, 17 Nov 2025 21:02:31 GMT + - Mon, 17 Nov 2025 22:02:35 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -134,7 +134,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:32 GMT + - Mon, 17 Nov 2025 22:02:35 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -186,7 +186,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:32 GMT + - Mon, 17 Nov 2025 22:02:36 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -238,7 +238,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:33 GMT + - Mon, 17 Nov 2025 22:02:36 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: @@ -290,7 +290,7 @@ interactions: Content-Type: - application/problem+json Date: - - Mon, 17 Nov 2025 21:02:33 GMT + - Mon, 17 Nov 2025 22:02:37 GMT Expires: - Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: diff --git a/tests/conftest.py b/tests/conftest.py index 48968be..4b3839a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,7 +16,7 @@ CASSETTE_USERNAME = "JOE" CASSETTE_PASSWORD = "NOTAPASSWORD" # pragma: allowlist secret -CASSETTE_ENDPOINT = "notauri.edu" +CASSETTE_ENDPOINT = "cleaned.example.edu" CASSETTE_CLIENT_ID = "FAKEID" CASSETTE_CLIENT_SECRET = "NOTASECRET" # pragma: allowlist secret From 2216614d2cd2a72a23ae456adf5b8f2ec19cfdf6 Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 11 Dec 2025 11:29:12 -0600 Subject: [PATCH 18/20] Fixup --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 4b3839a..892a92c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,7 +9,7 @@ from clearpass.client import APIConnection from vcr_cleaner import CleanYAMLSerializer from vcr_cleaner.filters import if_uri_endswith -from vcr_cleaner.cleaners import clean_domains +from vcr_cleaner.cleaners.uri import clean_domains # Set up logger logger = logging.getLogger(__name__) From fcdc652f59017757c65b1224b01b6b3496eec8f9 Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 11 Dec 2025 11:41:52 -0600 Subject: [PATCH 19/20] WIP - Test if `static` can pass with Python version set --- .python-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .python-version diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 From ca09a9d15fd4697472c4fc8827f18bdf15be90dd Mon Sep 17 00:00:00 2001 From: Edward Date: Fri, 12 Dec 2025 09:52:45 -0600 Subject: [PATCH 20/20] Update hand-crafted cassette to match updated serializer --- cassettes/test_failed_connectivity.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cassettes/test_failed_connectivity.yaml b/cassettes/test_failed_connectivity.yaml index 3a9ae4d..bd4b941 100644 --- a/cassettes/test_failed_connectivity.yaml +++ b/cassettes/test_failed_connectivity.yaml @@ -16,7 +16,7 @@ interactions: User-Agent: - python-requests/2.32.3 method: POST - uri: https://notauri.edu/api/oauth + uri: https://cleaned.example.edu/api/oauth response: body: string: '{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"invalid_client","status":400,"detail":"The