Files
orion/scripts/test_auth_complete.py
Samir Boulahtit fb8cb14506 refactor: rename public routes and templates to platform
Complete the public -> platform naming migration across the codebase.
This aligns with the naming convention where "platform" refers to
the marketing/public-facing pages of the platform itself.

Changes:
- Update all imports from public to platform modules
- Update template references from public/ to platform/
- Update route registrations to use platform prefix
- Update documentation to reflect new naming
- Update test files for platform API endpoints

Files affected:
- app/api/main.py - router imports
- app/modules/*/routes/*/platform.py - route definitions
- app/modules/*/templates/*/platform/ - template files
- app/modules/routes.py - route discovery
- docs/* - documentation updates
- tests/integration/api/v1/platform/ - test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:49:39 +01:00

555 lines
18 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Complete Authentication System Test Script
This script tests all three authentication contexts:
1. Admin authentication and cookie isolation
2. Vendor authentication and cookie isolation
3. Customer authentication and cookie isolation
4. Cross-context access prevention
5. Logging middleware
Usage:
python test_auth_complete.py
Requirements:
- Server running on http://localhost:8000
- Test users configured:
* Admin: username=admin, password=admin123
* Vendor: username=vendor, password=vendor123
* Customer: username=customer, password=customer123, vendor_id=1
"""
import requests
BASE_URL = "http://localhost:8000"
class Color:
"""Terminal colors for pretty output"""
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
MAGENTA = "\033[95m"
CYAN = "\033[96m"
BOLD = "\033[1m"
END = "\033[0m"
def print_section(name: str):
"""Print section header"""
print(f"\n{Color.BOLD}{Color.CYAN}{'' * 60}")
print(f" {name}")
print(f"{'' * 60}{Color.END}")
def print_test(name: str):
"""Print test name"""
print(f"\n{Color.BOLD}{Color.BLUE}🧪 Test: {name}{Color.END}")
def print_success(message: str):
"""Print success message"""
print(f"{Color.GREEN}{message}{Color.END}")
def print_error(message: str):
"""Print error message"""
print(f"{Color.RED}{message}{Color.END}")
def print_info(message: str):
"""Print info message"""
print(f"{Color.YELLOW} {message}{Color.END}")
def print_warning(message: str):
"""Print warning message"""
print(f"{Color.MAGENTA}⚠️ {message}{Color.END}")
# ============================================================================
# ADMIN AUTHENTICATION TESTS
# ============================================================================
def test_admin_login() -> dict | None:
"""Test admin login and cookie configuration"""
print_test("Admin Login")
try:
response = requests.post(
f"{BASE_URL}/api/v1/admin/auth/login",
json={"username": "admin", "password": "admin123"},
)
if response.status_code == 200:
data = response.json()
cookies = response.cookies
if "access_token" in data:
print_success("Admin login successful")
print_success(f"Received access token: {data['access_token'][:20]}...")
else:
print_error("No access token in response")
return None
if "admin_token" in cookies:
print_success("admin_token cookie set")
print_info("Cookie path should be /admin (verify in browser)")
else:
print_error("admin_token cookie NOT set")
return {"token": data["access_token"], "user": data.get("user", {})}
print_error(f"Login failed: {response.status_code}")
print_error(f"Response: {response.text}")
return None
except Exception as e:
print_error(f"Exception during admin login: {str(e)}")
return None
def test_admin_cannot_access_vendor_api(admin_token: str):
"""Test that admin token cannot access vendor API"""
print_test("Admin Token on Vendor API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/api/v1/vendor/TESTVENDOR/products",
headers={"Authorization": f"Bearer {admin_token}"},
)
if response.status_code in [401, 403]:
data = response.json()
print_success("Admin correctly blocked from vendor API")
print_success(f"Error code: {data.get('error_code', 'N/A')}")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Admin can access vendor API!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
def test_admin_cannot_access_customer_api(admin_token: str):
"""Test that admin token cannot access customer account pages"""
print_test("Admin Token on Customer API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/shop/account/dashboard",
headers={"Authorization": f"Bearer {admin_token}"},
)
# Customer pages may return HTML or JSON error
if response.status_code in [401, 403]:
print_success("Admin correctly blocked from customer pages")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Admin can access customer pages!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
# ============================================================================
# VENDOR AUTHENTICATION TESTS
# ============================================================================
def test_vendor_login() -> dict | None:
"""Test vendor login and cookie configuration"""
print_test("Vendor Login")
try:
response = requests.post(
f"{BASE_URL}/api/v1/vendor/auth/login",
json={"username": "vendor", "password": "vendor123"},
)
if response.status_code == 200:
data = response.json()
cookies = response.cookies
if "access_token" in data:
print_success("Vendor login successful")
print_success(f"Received access token: {data['access_token'][:20]}...")
else:
print_error("No access token in response")
return None
if "vendor_token" in cookies:
print_success("vendor_token cookie set")
print_info("Cookie path should be /vendor (verify in browser)")
else:
print_error("vendor_token cookie NOT set")
if "vendor" in data:
print_success(f"Vendor: {data['vendor'].get('vendor_code', 'N/A')}")
return {
"token": data["access_token"],
"user": data.get("user", {}),
"vendor": data.get("vendor", {}),
}
print_error(f"Login failed: {response.status_code}")
print_error(f"Response: {response.text}")
return None
except Exception as e:
print_error(f"Exception during vendor login: {str(e)}")
return None
def test_vendor_cannot_access_admin_api(vendor_token: str):
"""Test that vendor token cannot access admin API"""
print_test("Vendor Token on Admin API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/api/v1/admin/vendors",
headers={"Authorization": f"Bearer {vendor_token}"},
)
if response.status_code in [401, 403]:
data = response.json()
print_success("Vendor correctly blocked from admin API")
print_success(f"Error code: {data.get('error_code', 'N/A')}")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Vendor can access admin API!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
def test_vendor_cannot_access_customer_api(vendor_token: str):
"""Test that vendor token cannot access customer account pages"""
print_test("Vendor Token on Customer API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/shop/account/dashboard",
headers={"Authorization": f"Bearer {vendor_token}"},
)
if response.status_code in [401, 403]:
print_success("Vendor correctly blocked from customer pages")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Vendor can access customer pages!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
# ============================================================================
# CUSTOMER AUTHENTICATION TESTS
# ============================================================================
def test_customer_login() -> dict | None:
"""Test customer login and cookie configuration"""
print_test("Customer Login")
try:
response = requests.post(
f"{BASE_URL}/api/v1/platform/vendors/1/customers/login",
json={"username": "customer", "password": "customer123"},
)
if response.status_code == 200:
data = response.json()
cookies = response.cookies
if "access_token" in data:
print_success("Customer login successful")
print_success(f"Received access token: {data['access_token'][:20]}...")
else:
print_error("No access token in response")
return None
if "customer_token" in cookies:
print_success("customer_token cookie set")
print_info("Cookie path should be /shop (verify in browser)")
else:
print_error("customer_token cookie NOT set")
return {"token": data["access_token"], "user": data.get("user", {})}
print_error(f"Login failed: {response.status_code}")
print_error(f"Response: {response.text}")
return None
except Exception as e:
print_error(f"Exception during customer login: {str(e)}")
return None
def test_customer_cannot_access_admin_api(customer_token: str):
"""Test that customer token cannot access admin API"""
print_test("Customer Token on Admin API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/api/v1/admin/vendors",
headers={"Authorization": f"Bearer {customer_token}"},
)
if response.status_code in [401, 403]:
data = response.json()
print_success("Customer correctly blocked from admin API")
print_success(f"Error code: {data.get('error_code', 'N/A')}")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Customer can access admin API!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
def test_customer_cannot_access_vendor_api(customer_token: str):
"""Test that customer token cannot access vendor API"""
print_test("Customer Token on Vendor API (Should Block)")
try:
response = requests.get(
f"{BASE_URL}/api/v1/vendor/TESTVENDOR/products",
headers={"Authorization": f"Bearer {customer_token}"},
)
if response.status_code in [401, 403]:
data = response.json()
print_success("Customer correctly blocked from vendor API")
print_success(f"Error code: {data.get('error_code', 'N/A')}")
return True
if response.status_code == 200:
print_error("SECURITY ISSUE: Customer can access vendor API!")
return False
print_warning(f"Unexpected status code: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
def test_public_shop_access():
"""Test that public shop pages are accessible without authentication"""
print_test("Public Shop Access (No Auth Required)")
try:
response = requests.get(f"{BASE_URL}/shop/products")
if response.status_code == 200:
print_success("Public shop pages accessible without auth")
return True
print_error(f"Failed to access public shop: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
def test_health_check():
"""Test health check endpoint"""
print_test("Health Check")
try:
response = requests.get(f"{BASE_URL}/health")
if response.status_code == 200:
data = response.json()
print_success("Health check passed")
print_info(f"Status: {data.get('status', 'N/A')}")
return True
print_error(f"Health check failed: {response.status_code}")
return False
except Exception as e:
print_error(f"Exception: {str(e)}")
return False
# ============================================================================
# MAIN TEST RUNNER
# ============================================================================
def main():
"""Run all tests"""
print(f"\n{Color.BOLD}{Color.CYAN}{'' * 60}")
print(" 🔒 COMPLETE AUTHENTICATION SYSTEM TEST SUITE")
print(f"{'' * 60}{Color.END}")
print(f"Testing server at: {BASE_URL}")
results = {"passed": 0, "failed": 0, "total": 0}
# Health check first
print_section("🏥 System Health")
results["total"] += 1
if test_health_check():
results["passed"] += 1
else:
results["failed"] += 1
print_error("Server not responding. Is it running?")
return
# ========================================================================
# ADMIN TESTS
# ========================================================================
print_section("👤 Admin Authentication Tests")
# Admin login
results["total"] += 1
admin_auth = test_admin_login()
if admin_auth:
results["passed"] += 1
else:
results["failed"] += 1
admin_auth = None
# Admin cross-context tests
if admin_auth:
results["total"] += 1
if test_admin_cannot_access_vendor_api(admin_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
results["total"] += 1
if test_admin_cannot_access_customer_api(admin_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
# ========================================================================
# VENDOR TESTS
# ========================================================================
print_section("🏪 Vendor Authentication Tests")
# Vendor login
results["total"] += 1
vendor_auth = test_vendor_login()
if vendor_auth:
results["passed"] += 1
else:
results["failed"] += 1
vendor_auth = None
# Vendor cross-context tests
if vendor_auth:
results["total"] += 1
if test_vendor_cannot_access_admin_api(vendor_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
results["total"] += 1
if test_vendor_cannot_access_customer_api(vendor_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
# ========================================================================
# CUSTOMER TESTS
# ========================================================================
print_section("🛒 Customer Authentication Tests")
# Public shop access
results["total"] += 1
if test_public_shop_access():
results["passed"] += 1
else:
results["failed"] += 1
# Customer login
results["total"] += 1
customer_auth = test_customer_login()
if customer_auth:
results["passed"] += 1
else:
results["failed"] += 1
customer_auth = None
# Customer cross-context tests
if customer_auth:
results["total"] += 1
if test_customer_cannot_access_admin_api(customer_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
results["total"] += 1
if test_customer_cannot_access_vendor_api(customer_auth["token"]):
results["passed"] += 1
else:
results["failed"] += 1
# ========================================================================
# RESULTS
# ========================================================================
print_section("📊 Test Results")
print(f"\n{Color.BOLD}Total Tests: {results['total']}{Color.END}")
print_success(f"Passed: {results['passed']}")
if results["failed"] > 0:
print_error(f"Failed: {results['failed']}")
if results["failed"] == 0:
print(f"\n{Color.GREEN}{Color.BOLD}🎉 ALL TESTS PASSED!{Color.END}")
print(
f"{Color.GREEN}Your authentication system is properly isolated!{Color.END}"
)
else:
print(f"\n{Color.RED}{Color.BOLD}⚠️ SOME TESTS FAILED{Color.END}")
print(f"{Color.RED}Please review the output above.{Color.END}")
# Browser tests reminder
print_section("🌐 Manual Browser Tests")
print("Please also verify in browser:")
print("\n1. Open DevTools → Application → Cookies")
print("\n2. Log in as admin:")
print(" - Cookie name: admin_token")
print(" - Path: /admin")
print(" - HttpOnly: ✓")
print("\n3. Log in as vendor:")
print(" - Cookie name: vendor_token")
print(" - Path: /vendor")
print(" - HttpOnly: ✓")
print("\n4. Log in as customer:")
print(" - Cookie name: customer_token")
print(" - Path: /shop")
print(" - HttpOnly: ✓")
print("\n5. Verify cross-context isolation:")
print(" - Admin cookie NOT sent to /vendor/* or /shop/*")
print(" - Vendor cookie NOT sent to /admin/* or /shop/*")
print(" - Customer cookie NOT sent to /admin/* or /vendor/*")
print(f"\n{Color.CYAN}{'' * 60}{Color.END}\n")
if __name__ == "__main__":
main()