mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
fix: resolve config mismatch + auth security hardening
P0: config.py defined hanzo_commerce_* but billing code accessed settings.commerce_* — causes AttributeError at runtime. Renamed fields with AliasChoices for backward compat with HANZO_COMMERCE_* env vars. P1: deps.py silently swallowed JWT errors (bare pass) — now logs them. Virtual API key used fake UUID for missing projects — now raises 404. Updated secrets.yaml to replace stale Stripe references with Commerce.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""API dependencies."""
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import uuid
|
||||
from typing import Annotated
|
||||
|
||||
@@ -14,6 +15,7 @@ from bootnode.core.cache import redis_client
|
||||
from bootnode.db.models import ApiKey, Project, User
|
||||
from bootnode.db.session import get_db
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
settings = get_settings()
|
||||
|
||||
|
||||
@@ -63,9 +65,9 @@ async def verify_api_key_or_token(
|
||||
)
|
||||
project = proj_result.scalar_one_or_none()
|
||||
return None, user, project
|
||||
except jwt.InvalidTokenError:
|
||||
except jwt.InvalidTokenError as e:
|
||||
logger.debug("JWT verification failed: %s", e)
|
||||
# Not a valid JWT, try as API key
|
||||
pass
|
||||
|
||||
# Try API key
|
||||
key_hash = hashlib.sha256(
|
||||
@@ -120,10 +122,14 @@ async def verify_api_key(
|
||||
|
||||
# For JWT auth, create a virtual API key with user permissions
|
||||
if user:
|
||||
# Return a mock API key object for JWT-authenticated users
|
||||
if not project:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No project found. Create a project first.",
|
||||
)
|
||||
virtual_key = ApiKey(
|
||||
id=uuid.uuid4(),
|
||||
project_id=project.id if project else uuid.UUID('00000000-0000-0000-0000-000000000001'),
|
||||
project_id=project.id,
|
||||
name=f"User: {user.email}",
|
||||
key_hash="jwt-auth",
|
||||
key_prefix="jwt_",
|
||||
|
||||
+15
-5
@@ -3,7 +3,7 @@
|
||||
from functools import lru_cache
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import Field, PostgresDsn, RedisDsn
|
||||
from pydantic import AliasChoices, Field, PostgresDsn, RedisDsn
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@@ -108,10 +108,20 @@ class Settings(BaseSettings):
|
||||
webhook_timeout: int = 30
|
||||
webhook_max_retries: int = 5
|
||||
|
||||
# Hanzo Commerce (Stripe-based billing)
|
||||
hanzo_commerce_url: str = "https://commerce.hanzo.ai"
|
||||
hanzo_commerce_api_key: str = ""
|
||||
hanzo_commerce_webhook_secret: str = ""
|
||||
# Hanzo Commerce (Square-based billing)
|
||||
# Accepts both COMMERCE_URL and HANZO_COMMERCE_URL env vars for backward compat
|
||||
commerce_url: str = Field(
|
||||
default="https://commerce.hanzo.ai",
|
||||
validation_alias=AliasChoices("commerce_url", "hanzo_commerce_url"),
|
||||
)
|
||||
commerce_api_key: str = Field(
|
||||
default="",
|
||||
validation_alias=AliasChoices("commerce_api_key", "hanzo_commerce_api_key"),
|
||||
)
|
||||
commerce_webhook_secret: str = Field(
|
||||
default="",
|
||||
validation_alias=AliasChoices("commerce_webhook_secret", "hanzo_commerce_webhook_secret"),
|
||||
)
|
||||
|
||||
# ERC-4337 Bundler
|
||||
bundler_private_key: str = ""
|
||||
|
||||
@@ -34,9 +34,7 @@ type: Opaque
|
||||
# stringData intentionally empty - use KMS or kubectl create secret
|
||||
# Required secrets (inject via KMS, kubectl, or sealed-secrets):
|
||||
# database-url, redis-url, jwt-secret, api-key-salt
|
||||
# stripe-secret-key, stripe-webhook-secret, stripe-publishable-key
|
||||
# stripe-product-id, stripe-price-payg
|
||||
# stripe-price-growth-base, stripe-price-growth-metered
|
||||
# commerce-url, commerce-api-key, commerce-webhook-secret
|
||||
stringData: {}
|
||||
---
|
||||
# Chain configuration (non-sensitive)
|
||||
|
||||
Reference in New Issue
Block a user