133 lines
4.3 KiB
Python
133 lines
4.3 KiB
Python
"""
|
|
Authentication utilities for Wix API requests.
|
|
|
|
Supports both OAuth Bearer tokens and API keys for Wix Headless apps.
|
|
"""
|
|
|
|
import os
|
|
from typing import Dict, Optional
|
|
from loguru import logger
|
|
|
|
|
|
def get_wix_headers(
|
|
access_token: str,
|
|
client_id: Optional[str] = None,
|
|
extra: Optional[Dict[str, str]] = None
|
|
) -> Dict[str, str]:
|
|
"""
|
|
Build headers for Wix API requests with automatic token type detection.
|
|
|
|
Supports:
|
|
- OAuth Bearer tokens (JWT format: xxx.yyy.zzz)
|
|
- Wix API keys (for Headless apps)
|
|
|
|
Args:
|
|
access_token: OAuth token OR API key
|
|
client_id: Optional Wix client ID
|
|
extra: Additional headers to include
|
|
|
|
Returns:
|
|
Headers dict with proper Authorization format
|
|
"""
|
|
headers: Dict[str, str] = {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
|
|
if access_token:
|
|
# Ensure access_token is a string (defensive check)
|
|
if not isinstance(access_token, str):
|
|
from services.integrations.wix.utils import normalize_token_string
|
|
normalized = normalize_token_string(access_token)
|
|
if normalized:
|
|
access_token = normalized
|
|
else:
|
|
access_token = str(access_token)
|
|
|
|
token = access_token.strip()
|
|
if token:
|
|
# Detect token type
|
|
# API keys are typically longer and don't have JWT structure (xxx.yyy.zzz)
|
|
# JWT tokens have exactly 2 dots separating 3 parts
|
|
# Wix OAuth tokens can have format "OauthNG.JWS.xxx.yyy.zzz"
|
|
|
|
# CRITICAL: Wix OAuth tokens can have format "OauthNG.JWS.xxx.yyy.zzz"
|
|
# These should use "Bearer" prefix even though they have more than 2 dots
|
|
if token.startswith('OauthNG.JWS.'):
|
|
# Wix OAuth token - use Bearer prefix
|
|
headers['Authorization'] = f'Bearer {token}'
|
|
logger.debug(f"Using Wix OAuth token with Bearer prefix (OauthNG.JWS. format detected)")
|
|
else:
|
|
# Count dots - JWT has exactly 2 dots
|
|
dot_count = token.count('.')
|
|
|
|
if dot_count == 2 and len(token) < 500:
|
|
# Likely OAuth JWT token - use Bearer prefix
|
|
headers['Authorization'] = f'Bearer {token}'
|
|
logger.debug(f"Using OAuth Bearer token (JWT format detected)")
|
|
else:
|
|
# Likely API key - use directly without Bearer prefix
|
|
headers['Authorization'] = token
|
|
logger.debug(f"Using API key for authorization (non-JWT format detected)")
|
|
|
|
if client_id:
|
|
headers['wix-client-id'] = client_id
|
|
|
|
if extra:
|
|
headers.update(extra)
|
|
|
|
return headers
|
|
|
|
|
|
def get_wix_api_key() -> Optional[str]:
|
|
"""
|
|
Get Wix API key from environment.
|
|
|
|
For Wix Headless apps, API keys provide admin-level access.
|
|
|
|
Returns:
|
|
API key if set, None otherwise
|
|
"""
|
|
api_key = os.getenv('WIX_API_KEY')
|
|
if api_key:
|
|
logger.warning(f"✅ Wix API key found in environment ({len(api_key)} chars)")
|
|
else:
|
|
logger.warning("❌ No Wix API key in environment")
|
|
return api_key
|
|
|
|
|
|
def should_use_api_key(access_token: Optional[str] = None) -> bool:
|
|
"""
|
|
Determine if we should use API key instead of OAuth token.
|
|
|
|
Use API key if:
|
|
- No OAuth token provided
|
|
- OAuth token is getting 403 errors
|
|
- API key is available in environment
|
|
|
|
Args:
|
|
access_token: Optional OAuth token
|
|
|
|
Returns:
|
|
True if should use API key, False otherwise
|
|
"""
|
|
# If no access token, check for API key
|
|
if not access_token or not access_token.strip():
|
|
return get_wix_api_key() is not None
|
|
|
|
# If access token looks like API key already, use it
|
|
# Ensure access_token is a string (defensive check)
|
|
if not isinstance(access_token, str):
|
|
from services.integrations.wix.utils import normalize_token_string
|
|
normalized = normalize_token_string(access_token)
|
|
if normalized:
|
|
access_token = normalized
|
|
else:
|
|
access_token = str(access_token)
|
|
|
|
token = access_token.strip()
|
|
if token.count('.') != 2 or len(token) > 500:
|
|
return True
|
|
|
|
return False
|
|
|