feat(oidc): add debug logging and migrate client secret hashing to Flask-Bcrypt

- Add comprehensive debug logging across OIDC endpoints and services for development troubleshooting
- Implement backward-compatible password hash checking with automatic migration from raw bcrypt to Flask-Bcrypt format
- Refactor logging configuration to ensure proper propagation across all app modules
- Configure root logger and disable Werkzeug duplication for cleaner log output
- Initialize OIDC JWKS service on application startup
- Update seed script to use Flask-Bcrypt for client secret hashing
- Fix audit service to use correct event_metadata parameter

BREAKING CHANGE: Client secrets created with old raw bcrypt format will be automatically migrated to Flask-Bcrypt format on first successful authentication
This commit is contained in:
2026-01-09 12:59:53 +10:30
parent 5e060f267d
commit a6474f55c1
8 changed files with 348 additions and 21 deletions
+16 -1
View File
@@ -1,10 +1,14 @@
"""User service."""
import logging
from flask import current_app
from app.extensions import db
from app.models.user import User
from app.exceptions.validation_exceptions import UserNotFoundError
from app.utils.constants import AuditAction
from app.services.audit_service import AuditService
logger = logging.getLogger(__name__)
class UserService:
"""Service for user operations."""
@@ -24,6 +28,11 @@ class UserService:
UserNotFoundError: If user not found
"""
user = User.query.filter_by(id=user_id, deleted_at=None).first()
# Development-only debug logging for user validation
if current_app.config.get('ENV') == 'development':
logger.debug(f"[User] Get user by ID: user_id={user_id}, exists={user is not None}")
if not user:
raise UserNotFoundError()
return user
@@ -39,7 +48,13 @@ class UserService:
Returns:
User instance or None
"""
return User.query.filter_by(email=email.lower(), deleted_at=None).first()
user = User.query.filter_by(email=email.lower(), deleted_at=None).first()
# Development-only debug logging for user validation
if current_app.config.get('ENV') == 'development':
logger.debug(f"[User] Get user by email: email={email}, exists={user is not None}")
return user
@staticmethod
def update_user(user, **kwargs):