frontend error management enhancement

This commit is contained in:
2025-11-05 21:52:22 +01:00
parent e4bc438069
commit 79dfcab09f
66 changed files with 7781 additions and 922 deletions

View File

@@ -29,7 +29,7 @@ from middleware.auth import AuthManager
from datetime import datetime, timezone
# Default credentials
DEFAULT_ADMIN_EMAIL = "admin@letzshop.com"
DEFAULT_ADMIN_EMAIL = "admin@wizamart.com"
DEFAULT_ADMIN_USERNAME = "admin"
DEFAULT_ADMIN_PASSWORD = "admin123" # Change in production!
@@ -268,7 +268,7 @@ def seed_database():
for v in vendors:
print(f"\n {v.vendor_code}")
print(f" Name: {v.name}")
print(f" Subdomain: {v.subdomain}.letzshop.com")
print(f" Subdomain: {v.subdomain}.wizamart.com")
print(f" Theme URL: http://localhost:8000/admin/vendors/{v.vendor_code}/theme")
print(f" Verified: {'' if v.is_verified else ''}")
print(f" Active: {'' if v.is_active else ''}")

View File

@@ -1,5 +1,6 @@
@echo off
echo Generating frontend structure...
setlocal enabledelayedexpansion
echo Generating frontend structure with statistics...
echo.
set OUTPUT=frontend-structure.txt
@@ -9,10 +10,57 @@ echo Generated: %date% %time% >> %OUTPUT%
echo ============================================================================== >> %OUTPUT%
echo. >> %OUTPUT%
echo. >> %OUTPUT%
echo ╔══════════════════════════════════════════════════════════════════╗ >> %OUTPUT%
echo ║ JINJA2 TEMPLATES ║ >> %OUTPUT%
echo ║ Location: app/templates ║ >> %OUTPUT%
echo ╚══════════════════════════════════════════════════════════════════╝ >> %OUTPUT%
echo. >> %OUTPUT%
tree /F /A app\templates >> %OUTPUT%
echo. >> %OUTPUT%
echo. >> %OUTPUT%
echo ╔══════════════════════════════════════════════════════════════════╗ >> %OUTPUT%
echo ║ STATIC ASSETS ║ >> %OUTPUT%
echo ║ Location: static ║ >> %OUTPUT%
echo ╚══════════════════════════════════════════════════════════════════╝ >> %OUTPUT%
echo. >> %OUTPUT%
tree /F /A static >> %OUTPUT%
echo. >> %OUTPUT%
echo. >> %OUTPUT%
echo ╔══════════════════════════════════════════════════════════════════╗ >> %OUTPUT%
echo ║ STATISTICS ║ >> %OUTPUT%
echo ╚══════════════════════════════════════════════════════════════════╝ >> %OUTPUT%
echo. >> %OUTPUT%
echo Templates: >> %OUTPUT%
echo - Total HTML files: >> %OUTPUT%
dir /S /B app\templates\*.html 2>nul | find /C ".html" >> %OUTPUT%
echo - Total Jinja2 files: >> %OUTPUT%
dir /S /B app\templates\*.j2 2>nul | find /C ".j2" >> %OUTPUT%
echo. >> %OUTPUT%
echo Static Assets: >> %OUTPUT%
echo - JavaScript files: >> %OUTPUT%
dir /S /B static\*.js 2>nul | find /C ".js" >> %OUTPUT%
echo - CSS files: >> %OUTPUT%
dir /S /B static\*.css 2>nul | find /C ".css" >> %OUTPUT%
echo - Image files: >> %OUTPUT%
for %%e in (png jpg jpeg gif svg webp ico) do (
dir /S /B static\*.%%e 2>nul | find /C ".%%e" >> %OUTPUT%
)
echo. >> %OUTPUT%
echo ============================================================================== >> %OUTPUT%
echo End of structure >> %OUTPUT%
echo.
echo ✅ Structure saved to %OUTPUT%
echo.
echo Opening file...
notepad %OUTPUT%
notepad %OUTPUT%
endlocal

View File

@@ -0,0 +1,562 @@
#!/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
import json
from typing import Dict, Optional
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() -> Optional[Dict]:
"""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", {})
}
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Admin can access vendor API!")
return False
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Admin can access customer pages!")
return False
else:
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() -> Optional[Dict]:
"""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", {})
}
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Vendor can access admin API!")
return False
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Vendor can access customer pages!")
return False
else:
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() -> Optional[Dict]:
"""Test customer login and cookie configuration"""
print_test("Customer Login")
try:
response = requests.post(
f"{BASE_URL}/api/v1/public/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", {})
}
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Customer can access admin API!")
return False
else:
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
elif response.status_code == 200:
print_error("SECURITY ISSUE: Customer can access vendor API!")
return False
else:
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
else:
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
else:
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(f" 🔒 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()