make_post_sell/debug_auth_headers.py
Russell Ballestrini 800b7965b5 Fix crypto watcher stuck payments and improve cart deactivation
- Exclude already-swept payments from watcher queue to prevent endless processing
- Mark swept payments as "swept" status to remove from future cycles
- Fix cart deactivation by ensuring shop/user objects are attached to session
- Add debug logging for cart deactivation to track behavior
- Resolves issue where confirmed payments were processed every 20 seconds indefinitely

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 12:35:56 -04:00

76 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
Debug script to examine the exact WWW-Authenticate header
that Monero wallet RPC sends and how urllib handles it.
"""
import urllib.request
import urllib.error
import json
def examine_auth_challenge():
"""Look at the WWW-Authenticate header from the server"""
print("=== Examining Authentication Challenge ===")
rpc_url = "http://127.0.0.1:18083/json_rpc"
payload = {"jsonrpc": "2.0", "id": 1, "method": "get_height"}
data = json.dumps(payload).encode()
# Make request without auth to get the challenge
req = urllib.request.Request(
rpc_url, data=data, headers={"Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req) as resp:
print("Unexpected: No auth required")
return None
except urllib.error.HTTPError as e:
if e.code == 401:
www_auth = e.headers.get("WWW-Authenticate", "")
print(f"WWW-Authenticate header: {www_auth!r}")
# Parse it
if www_auth.startswith("Digest "):
challenge = www_auth[7:].strip()
print(f"Challenge details: {challenge}")
# Parse individual components
import re
pattern = r'(\w+)=(?:"([^"]*)"|([^,\s]+))'
matches = re.findall(pattern, challenge)
print("Parsed components:")
for key, quoted_val, unquoted_val in matches:
val = quoted_val if quoted_val else unquoted_val
print(f" {key} = {val!r}")
return dict(
(key, quoted_val if quoted_val else unquoted_val)
for key, quoted_val, unquoted_val in matches
)
else:
print(f"Not Digest auth: {www_auth}")
return None
else:
print(f"Unexpected error: {e.code} {e.reason}")
return None
if __name__ == "__main__":
challenge = examine_auth_challenge()
if challenge:
print()
print("=== Analysis ===")
print(f"Realm: {challenge.get('realm', 'NOT SET')}")
print(f"Nonce: {challenge.get('nonce', 'NOT SET')}")
print(f"QOP: {challenge.get('qop', 'NOT SET')}")
print(f"Algorithm: {challenge.get('algorithm', 'NOT SET (defaults to MD5)')}")
# Check for any unusual parameters
standard_params = {"realm", "nonce", "qop", "algorithm", "opaque"}
extra_params = set(challenge.keys()) - standard_params
if extra_params:
print(f"Extra parameters: {extra_params}")