237 lines
6.1 KiB
Python
237 lines
6.1 KiB
Python
"""
|
|
API Key Service
|
|
|
|
Handles encrypted API key management for users.
|
|
|
|
Usage:
|
|
from apps.chatbot.services import APIKeyService
|
|
|
|
# Store user's API key
|
|
api_key = APIKeyService.create_api_key(
|
|
user=user,
|
|
provider="openai",
|
|
api_key="sk-...",
|
|
key_name="My OpenAI Key"
|
|
)
|
|
"""
|
|
|
|
from typing import Optional, List
|
|
from uuid import UUID
|
|
|
|
from apps.chatbot.models import UserAPIKey
|
|
from apps.accounts.models import CustomUser
|
|
|
|
|
|
class APIKeyService:
|
|
"""Service for managing user API keys."""
|
|
|
|
@staticmethod
|
|
def create_api_key(
|
|
user: CustomUser,
|
|
provider: str,
|
|
api_key: str,
|
|
key_name: Optional[str] = None,
|
|
is_default: bool = False
|
|
) -> UserAPIKey:
|
|
"""
|
|
Create and encrypt user API key.
|
|
|
|
Args:
|
|
user: The user
|
|
provider: Provider name (openai, anthropic, etc.)
|
|
api_key: The actual API key (will be encrypted)
|
|
key_name: User-friendly name
|
|
is_default: Set as default key for provider
|
|
|
|
Returns:
|
|
Created UserAPIKey instance
|
|
|
|
Example:
|
|
api_key = APIKeyService.create_api_key(
|
|
user=request.user,
|
|
provider="openai",
|
|
api_key="sk-proj-...",
|
|
key_name="My OpenAI Key",
|
|
is_default=True
|
|
)
|
|
"""
|
|
# If setting as default, unset other defaults
|
|
if is_default:
|
|
UserAPIKey.objects.filter(
|
|
user=user,
|
|
provider=provider,
|
|
is_default=True
|
|
).update(is_default=False)
|
|
|
|
# Create key
|
|
user_api_key = UserAPIKey.objects.create(
|
|
user=user,
|
|
provider=provider,
|
|
key_name=key_name or f"{provider.title()} Key",
|
|
is_default=is_default
|
|
)
|
|
|
|
# Encrypt and save
|
|
user_api_key.encrypt_api_key(api_key)
|
|
user_api_key.save()
|
|
|
|
return user_api_key
|
|
|
|
@staticmethod
|
|
def get_user_keys(
|
|
user: CustomUser,
|
|
provider: Optional[str] = None
|
|
) -> List[UserAPIKey]:
|
|
"""
|
|
Get user's API keys.
|
|
|
|
Args:
|
|
user: The user
|
|
provider: Filter by provider (optional)
|
|
|
|
Returns:
|
|
List of UserAPIKey instances
|
|
"""
|
|
query = UserAPIKey.objects.filter(user=user, is_active=True)
|
|
|
|
if provider:
|
|
query = query.filter(provider=provider)
|
|
|
|
return list(query.order_by('-is_default', '-created_at'))
|
|
|
|
@staticmethod
|
|
def get_default_key(
|
|
user: CustomUser,
|
|
provider: str
|
|
) -> Optional[UserAPIKey]:
|
|
"""
|
|
Get user's default key for a provider.
|
|
|
|
Args:
|
|
user: The user
|
|
provider: Provider name
|
|
|
|
Returns:
|
|
UserAPIKey instance or None
|
|
"""
|
|
try:
|
|
return UserAPIKey.objects.get(
|
|
user=user,
|
|
provider=provider,
|
|
is_default=True,
|
|
is_active=True
|
|
)
|
|
except UserAPIKey.DoesNotExist:
|
|
# Try to get any active key
|
|
try:
|
|
return UserAPIKey.objects.filter(
|
|
user=user,
|
|
provider=provider,
|
|
is_active=True
|
|
).first()
|
|
except:
|
|
return None
|
|
|
|
@staticmethod
|
|
def get_decrypted_key(
|
|
user: CustomUser,
|
|
provider: str
|
|
) -> Optional[str]:
|
|
"""
|
|
Get decrypted API key for provider.
|
|
|
|
Args:
|
|
user: The user
|
|
provider: Provider name
|
|
|
|
Returns:
|
|
Decrypted API key or None
|
|
|
|
Example:
|
|
api_key = APIKeyService.get_decrypted_key(
|
|
user=request.user,
|
|
provider="openai"
|
|
)
|
|
|
|
if api_key:
|
|
# Use key with OpenAI
|
|
client = OpenAI(api_key=api_key)
|
|
"""
|
|
user_api_key = APIKeyService.get_default_key(user, provider)
|
|
|
|
if user_api_key:
|
|
return user_api_key.decrypt_api_key()
|
|
|
|
return None
|
|
|
|
@staticmethod
|
|
def validate_key(
|
|
user: CustomUser,
|
|
key_id: UUID
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Validate an API key.
|
|
|
|
Args:
|
|
user: The user
|
|
key_id: UserAPIKey ID
|
|
|
|
Returns:
|
|
Validation result dict
|
|
"""
|
|
user_api_key = UserAPIKey.objects.get(id=key_id, user=user)
|
|
result = user_api_key.validate_key()
|
|
|
|
if result['valid']:
|
|
user_api_key.is_validated = True
|
|
user_api_key.save()
|
|
|
|
return result
|
|
|
|
@staticmethod
|
|
def delete_key(
|
|
user: CustomUser,
|
|
key_id: UUID
|
|
) -> None:
|
|
"""
|
|
Delete an API key.
|
|
|
|
Args:
|
|
user: The user
|
|
key_id: UserAPIKey ID
|
|
"""
|
|
UserAPIKey.objects.filter(
|
|
id=key_id,
|
|
user=user
|
|
).delete()
|
|
|
|
@staticmethod
|
|
def set_default_key(
|
|
user: CustomUser,
|
|
key_id: UUID
|
|
) -> UserAPIKey:
|
|
"""
|
|
Set a key as default for its provider.
|
|
|
|
Args:
|
|
user: The user
|
|
key_id: UserAPIKey ID
|
|
|
|
Returns:
|
|
Updated UserAPIKey instance
|
|
"""
|
|
user_api_key = UserAPIKey.objects.get(id=key_id, user=user)
|
|
|
|
# Unset other defaults
|
|
UserAPIKey.objects.filter(
|
|
user=user,
|
|
provider=user_api_key.provider,
|
|
is_default=True
|
|
).update(is_default=False)
|
|
|
|
# Set as default
|
|
user_api_key.is_default = True
|
|
user_api_key.save()
|
|
|
|
return user_api_key
|