refactor(auth): Decouple BasicAuth and OAuth authentication strategies

Completely separates multi-user BasicAuth mode from OAuth mode with no
fallback between them. These are now mutually exclusive authentication
strategies based on deployment configuration.

Changes:
- Create separate functions: get_user_client_basic_auth() and
  get_user_client_oauth() with clear separation of concerns
- Update get_user_client() to dispatch based on use_basic_auth parameter
- Pass use_basic_auth through all background sync tasks
- Update app.py to determine auth mode at startup
- Rewrite integration tests to verify no OAuth fallback in BasicAuth mode
- Fix test assertions for response field names and duplicate title handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2025-12-25 08:27:15 -06:00
co-authored by Claude Opus 4.5
parent 804480836e
commit 894bf5f916
5 changed files with 390 additions and 136 deletions
+9 -2
View File
@@ -1841,6 +1841,11 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
)
break
# Determine authentication mode for background sync
# Multi-user BasicAuth: use app passwords via Astrolabe (NOT OAuth)
# OAuth mode: use OAuth refresh tokens (NOT app passwords)
use_basic_auth = not oauth_enabled
# Start background tasks using anyio TaskGroup
async with anyio_module.create_task_group() as tg:
# Start user manager task (supervises per-user scanners)
@@ -1849,11 +1854,12 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
send_stream,
shutdown_event,
scanner_wake_event,
token_broker,
token_broker if not use_basic_auth else None,
token_storage, # Use token_storage (works for both OAuth and multi-user BasicAuth)
nextcloud_host_for_sync,
user_states,
tg,
use_basic_auth, # Pass as positional arg (before task_status)
)
# Start processor pool (each gets a cloned receive stream)
@@ -1863,8 +1869,9 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
i,
receive_stream.clone(),
shutdown_event,
token_broker,
token_broker if not use_basic_auth else None,
nextcloud_host_for_sync,
use_basic_auth, # Pass as positional arg (before task_status)
)
logger.info(