Commit Graph
3 Commits
Author SHA1 Message Date
Chris CoutinhoandClaude Opus 4.7 8a0d06107e fix(api): use stored app password for chunk-context and pdf-preview
The /api/v1/chunk-context and /api/v1/pdf-preview handlers in
api/visualization.py forwarded the incoming OAuth bearer directly to
Nextcloud via NextcloudClient.from_token. In multi-user BasicAuth mode
Nextcloud has no validator for those bearers on Notes/WebDAV, so it
treats the request as anonymous and returns 401 — surfaced to the user
as a 500 from /apps/astrolabe/api/chunk-context. Search worked because
it only hits Qdrant.

Architecturally, OAuth is only for Astrolabe→MCP server; MCP server→
Nextcloud always uses the per-user app password stored during provision
(background sync already does this via vector.oauth_sync).

- Resolve the Nextcloud client through get_user_client_basic_auth in
  both get_chunk_context and get_pdf_preview, surfacing
  NotProvisionedError as a clean 401 instead of opaque 500.
- Apply the same fix to the session-cookie variant in
  auth/viz_routes.chunk_context_endpoint for the internal viz UI.

Tests:
- New unit file test_management_chunk_context_endpoint.py, including a
  regression guard that asserts get_user_client_basic_auth is awaited
  (so reverting to from_token fails without needing a live Nextcloud).
- Updated test_management_pdf_preview_endpoint.py to mock the new auth
  path (drops extract_bearer_token / NextcloudClient.from_token patches).
- New integration test test_astrolabe_chunk_context.py drives the full
  chain (browser → Astrolabe → MCP → Nextcloud) in multi-user BasicAuth
  mode, plus bare-bones 401 checks on the MCP endpoint.

Full unit suite: 546 passed.

Companion PR on astrolabe (cbcoutinho/astrolabe#66) sends the Nextcloud
UID as loginName in the app-password POST body so the stored record is
complete. Submodule bump to that branch will follow once CI reproduces
the failure on the old submodule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 19:50:13 +02:00
Chris CoutinhoandClaude Opus 4.6 a11ae9c027 refactor: enforce PLC0415 (import-outside-top-level) for source code
Enable ruff PLC0415 rule for all source files (tests excluded via
per-file-ignores). Move 136 inline imports to top-level across 33 files.
8 imports suppressed with noqa for legitimate reasons: circular
dependencies (client/__init__.py, context.py), optional dependency
guards (app.py document processors, auth/userinfo_routes.py), and
post-env-setup imports (smithery_main.py).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 08:04:50 +01:00
Chris CoutinhoandClaude Opus 4.5 2e7774654b refactor(api): split management.py into domain-focused modules
Split the monolithic management.py (1988 lines) into 4 focused modules:
- management.py: Server status, user sessions, shared helpers (~520 lines)
- passwords.py: App password provisioning for BasicAuth mode (~300 lines)
- webhooks.py: Webhook registration management (~290 lines)
- visualization.py: Search and PDF preview endpoints (~810 lines)

Backward compatibility maintained via __init__.py re-exports.
Updated test imports to use new module paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 21:28:18 +01:00