#!/usr/bin/env python3 """ Complete Authentication System Test Script This script tests all three authentication contexts: 1. Admin authentication and cookie isolation 2. Store 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 * Store: username=store, password=store123 * Customer: username=customer, password=customer123, store_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_store_api(admin_token: str): """Test that admin token cannot access store API""" print_test("Admin Token on Store API (Should Block)") try: response = requests.get( f"{BASE_URL}/api/v1/store/TESTSTORE/products", headers={"Authorization": f"Bearer {admin_token}"}, ) if response.status_code in [401, 403]: data = response.json() print_success("Admin correctly blocked from store 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 store 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 # ============================================================================ # STORE AUTHENTICATION TESTS # ============================================================================ def test_store_login() -> dict | None: """Test store login and cookie configuration""" print_test("Store Login") try: response = requests.post( f"{BASE_URL}/api/v1/store/auth/login", json={"username": "store", "password": "store123"}, ) if response.status_code == 200: data = response.json() cookies = response.cookies if "access_token" in data: print_success("Store login successful") print_success(f"Received access token: {data['access_token'][:20]}...") else: print_error("No access token in response") return None if "store_token" in cookies: print_success("store_token cookie set") print_info("Cookie path should be /store (verify in browser)") else: print_error("store_token cookie NOT set") if "store" in data: print_success(f"Store: {data['store'].get('store_code', 'N/A')}") return { "token": data["access_token"], "user": data.get("user", {}), "store": data.get("store", {}), } 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 store login: {str(e)}") return None def test_store_cannot_access_admin_api(store_token: str): """Test that store token cannot access admin API""" print_test("Store Token on Admin API (Should Block)") try: response = requests.get( f"{BASE_URL}/api/v1/admin/stores", headers={"Authorization": f"Bearer {store_token}"}, ) if response.status_code in [401, 403]: data = response.json() print_success("Store 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: Store 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_store_cannot_access_customer_api(store_token: str): """Test that store token cannot access customer account pages""" print_test("Store Token on Customer API (Should Block)") try: response = requests.get( f"{BASE_URL}/shop/account/dashboard", headers={"Authorization": f"Bearer {store_token}"}, ) if response.status_code in [401, 403]: print_success("Store correctly blocked from customer pages") return True if response.status_code == 200: print_error("SECURITY ISSUE: Store 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/stores/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/stores", 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_store_api(customer_token: str): """Test that customer token cannot access store API""" print_test("Customer Token on Store API (Should Block)") try: response = requests.get( f"{BASE_URL}/api/v1/store/TESTSTORE/products", headers={"Authorization": f"Bearer {customer_token}"}, ) if response.status_code in [401, 403]: data = response.json() print_success("Customer correctly blocked from store 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 store 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") # noqa: SEC040, PERF040 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") # noqa: SEC040, PERF040 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_store_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 # ======================================================================== # STORE TESTS # ======================================================================== print_section("๐Ÿช Store Authentication Tests") # Store login results["total"] += 1 store_auth = test_store_login() if store_auth: results["passed"] += 1 else: results["failed"] += 1 store_auth = None # Store cross-context tests if store_auth: results["total"] += 1 if test_store_cannot_access_admin_api(store_auth["token"]): results["passed"] += 1 else: results["failed"] += 1 results["total"] += 1 if test_store_cannot_access_customer_api(store_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_store_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 store:") print(" - Cookie name: store_token") print(" - Path: /store") 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 /store/* or /shop/*") print(" - Store cookie NOT sent to /admin/* or /shop/*") print(" - Customer cookie NOT sent to /admin/* or /store/*") print(f"\n{Color.CYAN}{'โ•' * 60}{Color.END}\n") if __name__ == "__main__": main()