ferrero-opentext/Python-Version/scripts/test_connection.py
DJP 8e7ae7e2d2 Add optional mTLS certificate authentication with --auth-pfx flag
Implements dual authentication system: OAuth2 (default) + mTLS (opt-in).
Zero-risk implementation - existing OAuth2 workflows unchanged.

NEW FEATURE: mTLS Certificate Authentication
- PFX/P12 certificate support for enhanced security
- Activated ONLY with --auth-pfx command-line flag
- OAuth2 remains default (no flag = OAuth2 as before)
- Perfect for testing new auth without breaking production

USAGE:
  Default (OAuth2):
    python scripts/a1_to_a2_download.py

  With mTLS:
    python scripts/a1_to_a2_download.py --auth-pfx

IMPLEMENTATION:

1. Certificate Storage (SECURE):
   - NEW: config/certificates/ folder (gitignored)
   - Moved PFX file to secure location
   - File permissions: 600 (owner read/write only)
   - Password stored in .env (already gitignored)

2. Configuration:
   - .env: Added DAM_MTLS_CERT_PATH and DAM_MTLS_CERT_PASSWORD
   - config.yaml: Added mtls_cert_path and mtls_cert_password
   - .gitignore: Added config/certificates/, *.pfx, *.p12

3. DAM Client Dual Auth:
   - NEW: pfx_to_pem() - Converts PFX to temporary PEM for requests
   - UPDATED: __init__() - Accepts use_mtls flag
   - NEW: _make_api_request() - Unified request wrapper
   - Auto-selects auth method based on flag
   - Updated ALL 8 API calls to use wrapper

4. Scripts Updated (argparse):
   - test_connection.py - Added --auth-pfx flag
   - a1_to_a2_download.py - Added --auth-pfx flag
   - a5_to_a6_download.py - Added --auth-pfx flag
   - b1_to_b2_download.py - Added --auth-pfx flag

5. Test Script:
   - NEW: test_mtls_cert.py - Standalone cert loading test
   - Tests PFX→PEM conversion without API calls
   - Verifies certificate format and cleanup

TESTING RESULTS:
✓ Certificate loads successfully (10930 bytes)
✓ PFX→PEM conversion works (13520 bytes)
✓ Temp file cleanup working
✓ OAuth2 connection test: PASS
✓ mTLS connection test: PASS
✓ Both auth methods working independently

SECURITY:
✓ Certificate file gitignored
✓ Password in .env (gitignored)
✓ File permissions: 600
✓ Temp PEM files auto-deleted
✓ No secrets in code or config

MIGRATION PATH:
- Dev: Use dam-mtls-dev.pfx (current)
- Prod: Replace cert file, update password, same code

BACKWARD COMPATIBILITY:
✓ OAuth2 still default (100% backward compatible)
✓ Existing cron jobs unchanged
✓ No breaking changes
✓ Easy rollback (just don't use --auth-pfx)

Changes:
- .gitignore (+3 lines)
- Python-Version/.env (+3 lines)
- Python-Version/config/config.yaml (+3 lines)
- Python-Version/scripts/shared/dam_client.py (+100 lines dual auth)
- Python-Version/scripts/a1_to_a2_download.py (+14 lines argparse)
- Python-Version/scripts/a5_to_a6_download.py (+14 lines argparse)
- Python-Version/scripts/b1_to_b2_download.py (+14 lines argparse)
- Python-Version/scripts/test_connection.py (+15 lines argparse)
- NEW: Python-Version/scripts/test_mtls_cert.py (92 lines)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 18:01:23 -05:00

92 lines
2.7 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Test Connections - Verify DAM, Box, and Database connectivity
Supports both OAuth2 (default) and mTLS (--auth-pfx) authentication
"""
import sys
import os
import argparse
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from shared.config_loader import load_config
from shared.dam_client import DAMClient
from shared.box_client import BoxClient
from shared.database import Database
def main():
# Parse arguments
parser = argparse.ArgumentParser(description='Test Ferrero Automation Connections')
parser.add_argument('--auth-pfx', action='store_true',
help='Use mTLS certificate authentication instead of OAuth2')
args = parser.parse_args()
print("=" * 60)
print("Testing Ferrero Automation Connections")
if args.auth_pfx:
print("Authentication: mTLS Certificate (--auth-pfx)")
else:
print("Authentication: OAuth2 (default)")
print("=" * 60)
print("")
# Load config
try:
config = load_config('config/config.yaml')
print("✓ Configuration loaded")
except Exception as e:
print("✗ Configuration failed: {}".format(e))
sys.exit(1)
# Test DAM
print("")
print("Testing DAM connection...")
try:
dam = DAMClient(config, use_mtls=args.auth_pfx)
if dam.test_connection():
print("✓ DAM connection OK")
print(" URL: {}".format(config['dam']['base_url']))
if args.auth_pfx:
print(" Auth: mTLS Certificate")
else:
print(" Auth: OAuth2")
else:
print("✗ DAM connection failed")
except Exception as e:
print("✗ DAM error: {}".format(e))
# Test Box
print("")
print("Testing Box connection...")
try:
box = BoxClient(config)
if box.test_connection():
print("✓ Box connection OK")
print(" Enterprise ID: {}".format(config['box']['enterprise_id']))
else:
print("✗ Box connection failed")
except Exception as e:
print("✗ Box error: {}".format(e))
# Test Database
print("")
print("Testing Database connection...")
try:
db = Database(config)
if db.test_connection():
print("✓ Database connection OK")
print(" Host: {}:{}".format(config['database']['host'], config['database']['port']))
else:
print("✗ Database connection failed")
db.close()
except Exception as e:
print("✗ Database error: {}".format(e))
print("")
print("=" * 60)
print("Testing complete!")
print("=" * 60)
if __name__ == '__main__':
main()