Refactor OAuth provider linking and unlinking logic into a dedicated service; enhance error handling and logging throughout the application; improve sound management and scanning services with better file handling and unique naming; implement centralized error and logging services for consistent API responses and application-wide logging configuration.

This commit is contained in:
JSC
2025-07-05 13:07:06 +02:00
parent 41fc197f4c
commit e2fe451e5a
17 changed files with 758 additions and 352 deletions

View File

@@ -140,63 +140,27 @@ def link_provider(provider):
def link_callback(provider):
"""Handle OAuth callback for linking new provider."""
try:
from app.services.oauth_linking_service import OAuthLinkingService
current_user_id = get_jwt_identity()
if not current_user_id:
return {"error": "User not authenticated"}, 401
# Get current user from database
from app.models.user import User
user = User.query.get(current_user_id)
if not user:
return {"error": "User not found"}, 404
# Process OAuth callback but link to existing user
from authlib.integrations.flask_client import OAuth
from app.services.oauth_providers.registry import OAuthProviderRegistry
oauth = OAuth()
registry = OAuthProviderRegistry(oauth)
oauth_provider = registry.get_provider(provider)
if not oauth_provider:
return {"error": f"OAuth provider '{provider}' not configured"}, 400
token = oauth_provider.exchange_code_for_token(None, None)
raw_user_info = oauth_provider.get_user_info(token)
provider_data = oauth_provider.normalize_user_data(raw_user_info)
if not provider_data.get("id"):
return {
"error": "Failed to get user information from provider",
}, 400
# Check if this provider is already linked to another user
from app.models.user_oauth import UserOAuth
existing_provider = UserOAuth.find_by_provider_and_id(
result = OAuthLinkingService.link_provider_to_user(
provider,
provider_data["id"],
current_user_id,
)
return result
if existing_provider and existing_provider.user_id != user.id:
return {
"error": "This provider account is already linked to another user",
}, 409
# Link the provider to current user
UserOAuth.create_or_update(
user_id=user.id,
provider=provider,
provider_id=provider_data["id"],
email=provider_data["email"],
name=provider_data["name"],
picture=provider_data.get("picture"),
)
return {"message": f"{provider.title()} account linked successfully"}
except ValueError as e:
error_str = str(e)
if "not found" in error_str:
return {"error": error_str}, 404
if "not configured" in error_str:
return {"error": error_str}, 400
if "already linked" in error_str:
return {"error": error_str}, 409
return {"error": error_str}, 400
except Exception as e:
return {"error": str(e)}, 400
@@ -206,33 +170,27 @@ def link_callback(provider):
def unlink_provider(provider):
"""Unlink an OAuth provider from current user account."""
try:
from app.services.oauth_linking_service import OAuthLinkingService
current_user_id = get_jwt_identity()
if not current_user_id:
return {"error": "User not authenticated"}, 401
from app.database import db
from app.models.user import User
user = User.query.get(current_user_id)
if not user:
return {"error": "User not found"}, 404
# Check if user has more than one provider (prevent locking out)
if len(user.oauth_providers) <= 1:
return {"error": "Cannot unlink last authentication provider"}, 400
# Find and remove the provider
oauth_provider = user.get_provider(provider)
if not oauth_provider:
return {
"error": f"Provider '{provider}' not linked to this account",
}, 404
db.session.delete(oauth_provider)
db.session.commit()
return {"message": f"{provider.title()} account unlinked successfully"}
result = OAuthLinkingService.unlink_provider_from_user(
provider,
current_user_id,
)
return result
except ValueError as e:
error_str = str(e)
if "not found" in error_str:
return {"error": error_str}, 404
if "Cannot unlink" in error_str:
return {"error": error_str}, 400
if "not linked" in error_str:
return {"error": error_str}, 404
return {"error": error_str}, 400
except Exception as e:
return {"error": str(e)}, 400