make_post_sell/debug_digest_details.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

138 lines
4.8 KiB
Python

#!/usr/bin/env python3
"""
Debug script to examine the exact Digest authentication process
and identify potential issues with the Python urllib implementation.
"""
import urllib.request
import urllib.error
import http.client
import json
import hashlib
import secrets
def debug_digest_auth_process():
"""
Manually trace through the Digest authentication process to understand
what might be different from curl's implementation.
"""
print("=== Digest Authentication Debug Analysis ===")
print()
# Enable HTTP debugging to see what's being sent
http.client.HTTPConnection.debuglevel = 1
rpc_url = "http://127.0.0.1:18083/json_rpc"
rpc_user = "mps_xmr_user_5a4c3592d2b4b52d"
rpc_pass = "jLOnImOKWT1Vomeje3HvKBzsDjT6VPcxvf7FMtEpjvY4"
payload = {"jsonrpc": "2.0", "id": 1, "method": "get_height"}
data = json.dumps(payload).encode()
print("Step 1: Attempting initial request (should get 401 with WWW-Authenticate)")
# Make initial 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: Got response without auth required")
return
except urllib.error.HTTPError as e:
if e.code == 401:
print(f"✓ Got 401 as expected: {e.reason}")
auth_header = e.headers.get("WWW-Authenticate")
if auth_header:
print(f"WWW-Authenticate header: {auth_header}")
# Parse the challenge
if auth_header.startswith("Digest "):
print("✓ Server supports Digest authentication")
challenge_parts = auth_header[7:] # Remove 'Digest '
print(f"Challenge details: {challenge_parts}")
else:
print(f"⚠ Server wants {auth_header.split()[0]} auth, not Digest")
else:
print("✗ No WWW-Authenticate header found")
else:
print(f"Unexpected HTTP error: {e.code} {e.reason}")
print("\nStep 2: Now trying with Python's built-in Digest handler")
# Reset debug level for cleaner output
http.client.HTTPConnection.debuglevel = 0
# Try with the urllib digest handler
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, rpc_url, rpc_user, rpc_pass)
auth_handler = urllib.request.HTTPDigestAuthHandler(password_mgr)
opener = urllib.request.build_opener(auth_handler)
req = urllib.request.Request(
rpc_url, data=data, headers={"Content-Type": "application/json"}
)
try:
with opener.open(req) as resp:
result = json.loads(resp.read())
print("✓ Digest auth SUCCESS:", result)
except urllib.error.HTTPError as e:
print(f"✗ Digest auth FAILED: {e.code} {e.reason}")
# Try to get more details
if hasattr(e, "read"):
body = e.read().decode()
print(f"Response body: {body}")
def compare_with_requests_library():
"""
Compare urllib with the requests library to see if there's a difference.
This helps identify if it's a urllib-specific issue.
"""
print("\n=== Comparison with requests library ===")
try:
import requests
from requests.auth import HTTPDigestAuth
rpc_url = "http://127.0.0.1:18083/json_rpc"
rpc_user = "mps_xmr_user_5a4c3592d2b4b52d"
rpc_pass = "jLOnImOKWT1Vomeje3HvKBzsDjT6VPcxvf7FMtEpjvY4"
payload = {"jsonrpc": "2.0", "id": 1, "method": "get_height"}
print("Testing with requests library...")
response = requests.post(
rpc_url, json=payload, auth=HTTPDigestAuth(rpc_user, rpc_pass), timeout=15
)
if response.status_code == 200:
result = response.json()
print("✓ requests library SUCCESS:", result)
else:
print(
f"✗ requests library FAILED: {response.status_code} {response.reason}"
)
print(f"Response body: {response.text}")
except ImportError:
print("requests library not available for comparison")
except Exception as e:
print(f"requests library error: {e}")
if __name__ == "__main__":
debug_digest_auth_process()
compare_with_requests_library()
print("\n=== Summary ===")
print("This debug script helps identify:")
print("1. What WWW-Authenticate challenge the server sends")
print("2. Whether urllib's Digest implementation works correctly")
print("3. How different HTTP libraries handle the same credentials")
print()
print("Run this script on the production server where RPC auth is required.")