Commit bebce4e7 authored by Your Name's avatar Your Name

Fix Claude OAuth2 callback handling, raise version to 0.99.40

parent 156c2199
...@@ -54,7 +54,7 @@ from .auth.qwen import QwenOAuth2 ...@@ -54,7 +54,7 @@ from .auth.qwen import QwenOAuth2
from .handlers import RequestHandler, RotationHandler, AutoselectHandler from .handlers import RequestHandler, RotationHandler, AutoselectHandler
from .utils import count_messages_tokens, split_messages_into_chunks, get_max_request_tokens_for_model from .utils import count_messages_tokens, split_messages_into_chunks, get_max_request_tokens_for_model
__version__ = "0.99.39" __version__ = "0.99.40"
__all__ = [ __all__ = [
# Config # Config
"config", "config",
......
...@@ -12335,46 +12335,48 @@ async def dashboard_claude_auth_complete(request: Request): ...@@ -12335,46 +12335,48 @@ async def dashboard_claude_auth_complete(request: Request):
# Import ClaudeAuth # Import ClaudeAuth
from aisbf.auth.claude import ClaudeAuth from aisbf.auth.claude import ClaudeAuth
# Create auth instance
auth = ClaudeAuth()
auth.credentials_file = Path(credentials_file).expanduser()
# Use the new exchange_code_for_tokens method with retry logic
# Pass state as the second parameter (required), verifier as third (optional)
success = auth.exchange_code_for_tokens(code, state, verifier)
if success:
# Only the ONE config admin (user_id=None from aisbf.json) saves to file # Only the ONE config admin (user_id=None from aisbf.json) saves to file
# All other users (including database admins) save to database # All other users (including database admins) save to database
current_user_id = request.session.get('user_id') current_user_id = request.session.get('user_id')
is_config_admin = current_user_id is None is_config_admin = current_user_id is None
save_callback = None
if not is_config_admin: if not is_config_admin:
# Non-config-admin user: save credentials to database # For non-admin users, set up save_callback to save directly to database
provider_key = request.session.get('oauth2_provider')
def save_callback(creds):
try: try:
from aisbf.database import get_database from aisbf.database import get_database
db = DatabaseRegistry.get_config_database() db = DatabaseRegistry.get_config_database()
provider_key = request.session.get('oauth2_provider')
if db and current_user_id and provider_key: if db and current_user_id and provider_key:
# Read the credentials that were just saved to file
credentials_path = Path(credentials_file).expanduser()
if credentials_path.exists():
with open(credentials_path, 'r') as f:
db_credentials = json.load(f)
# Save to database
db.save_user_oauth2_credentials( db.save_user_oauth2_credentials(
user_id=current_user_id, user_id=current_user_id,
provider_id=provider_key, provider_id=provider_key,
auth_type='claude_oauth2', auth_type='claude_oauth2',
credentials=db_credentials credentials=creds
) )
logger.info(f"ClaudeOAuth2: Saved credentials to database for user {current_user_id}") logger.info(f"ClaudeOAuth2: Saved credentials to database for user {current_user_id}")
# Remove the file since we're using database storage for non-admin
credentials_path.unlink(missing_ok=True)
except Exception as e: except Exception as e:
logger.error(f"ClaudeOAuth2: Failed to save credentials to database: {e}") logger.error(f"ClaudeOAuth2: Failed to save credentials to database: {e}")
raise
# Create auth instance with proper save_callback
auth = ClaudeAuth(
credentials_file=credentials_file,
skip_initial_load=True,
save_callback=save_callback
)
# Use the new exchange_code_for_tokens method with retry logic
# Pass state as the second parameter (required), verifier as third (optional)
success = await auth.exchange_code_for_tokens(code, state, verifier)
if success:
# Clear temporary file for non-admin users (it was never written when using save_callback)
if not is_config_admin:
credentials_path = Path(credentials_file).expanduser()
credentials_path.unlink(missing_ok=True)
# Clear session data # Clear session data
request.session.pop('oauth2_code', None) request.session.pop('oauth2_code', None)
......
...@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" ...@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "aisbf" name = "aisbf"
version = "0.99.39" version = "0.99.40"
description = "AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations" description = "AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations"
readme = "README.md" readme = "README.md"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
......
...@@ -49,7 +49,7 @@ class InstallCommand(_install): ...@@ -49,7 +49,7 @@ class InstallCommand(_install):
setup( setup(
name="aisbf", name="aisbf",
version="0.99.39", version="0.99.40",
author="AISBF Contributors", author="AISBF Contributors",
author_email="stefy@nexlab.net", author_email="stefy@nexlab.net",
description="AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations", description="AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment