fix: use BYPASSRLS session for all auth deps and user-mutation endpoints
Phase 4 enabled RLS on the users table. All code paths that touch users (or other RLS-protected tables) before require_tenant_context sets app.current_account_id must use get_admin_db (BYPASSRLS): - deps.py: get_current_user and get_current_active_user → get_admin_db - auth.py: all endpoints → get_admin_db (login, register, refresh, etc. run before tenant context exists; mutation endpoints also need session consistency since current_user is in the admin session) - accounts.py: transfer_ownership, leave_account, delete_account → get_admin_db (these mutate current_user directly) - onboarding.py: dismiss_onboarding → get_admin_db (same reason) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ from sqlalchemy import select
|
||||
|
||||
from pydantic import BaseModel
|
||||
from app.core.database import get_db
|
||||
from app.core.admin_database import get_admin_db
|
||||
from app.core.subscriptions import get_account_subscription, get_plan_limits, get_account_usage
|
||||
from app.core.audit import log_audit
|
||||
from app.models.refresh_token import RefreshToken
|
||||
@@ -148,7 +149,7 @@ async def update_member_role(
|
||||
@router.post("/me/transfer-ownership", response_model=AccountResponse)
|
||||
async def transfer_ownership(
|
||||
data: TransferOwnershipRequest,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
db: Annotated[AsyncSession, Depends(get_admin_db)],
|
||||
current_user: Annotated[User, Depends(require_account_owner)]
|
||||
):
|
||||
"""Transfer account ownership to another member (owner only)."""
|
||||
@@ -377,7 +378,7 @@ async def list_invites(
|
||||
|
||||
@router.post("/me/leave")
|
||||
async def leave_account(
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
db: Annotated[AsyncSession, Depends(get_admin_db)],
|
||||
current_user: Annotated[User, Depends(get_current_active_user)]
|
||||
):
|
||||
"""Leave the current account (non-owners only). Creates a personal account."""
|
||||
@@ -423,7 +424,7 @@ class DeleteAccountRequest(BaseModel):
|
||||
@router.delete("/me")
|
||||
async def delete_account(
|
||||
data: DeleteAccountRequest,
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
db: Annotated[AsyncSession, Depends(get_admin_db)],
|
||||
current_user: Annotated[User, Depends(require_account_owner)]
|
||||
):
|
||||
"""Delete the current account and soft-delete the user (owner only, no other members)."""
|
||||
|
||||
Reference in New Issue
Block a user