Commit Graph
9 Commits
Author SHA1 Message Date
Chris CoutinhoandClaude Opus 4.7 f31d0544b7 fix(auth): invalidate scope cache on web/REST provisioning paths
The elicitation flow points users to the Astrolabe web route or the
BasicAuth REST endpoint to provision their app password. Both paths
stored the password without clearing the in-process scope cache, so a
user who provisioned through them would keep hitting
ProvisioningRequiredError for up to _SCOPE_CACHE_TTL (5 min) afterwards.

Add invalidate_scope_cache(user_id) to both write-paths (matching the
existing pattern in nc_auth_check_status), correct the now-misleading
comment in scope_authorization.py to name all three invalidation paths,
and add a one-line hint above the first elicitation patch in the test
file so future authors don't "fix" the patch target to the wrong module.

Addresses PR #757 round-3 review feedback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:59:53 +02:00
Chris CoutinhoandClaude Opus 4.7 f3256e515e refactor(config): consolidate NEXTCLOUD_PUBLIC_ISSUER_URL through Settings
Lift NEXTCLOUD_PUBLIC_ISSUER_URL out of raw os.getenv reads into
Settings.nextcloud_public_issuer_url across all 8 production call sites
(app.py x2, oauth_routes.py x2, browser_oauth_routes.py,
provision_routes.py, userinfo_routes.py, elicitation.py). cli.py
remains the env-write source so the existing config-by-flag pipeline
still works.

Also addresses remaining PR #757 review nits:
- elicitation.py: align URL-present/absent wording on "open in your
  browser" so users don't try clicking in the terminal
- test_scope_authorization_stored.py: lock in the deliberately-shared
  fall-through branch with explicit declined/cancelled decorator tests
- test_elicitation.py: switch from monkeypatch.setenv to
  patch(get_settings) since Settings is now the canonical surface

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:16:19 +02:00
Chris CoutinhoandClaude Opus 4.6 d06b862d24 fix: require bearer token on provision endpoints (open redirect mitigation)
Both /app/provision and /app/provision/status now require a valid
Nextcloud OIDC bearer token via the Authorization header, reusing the
existing validate_token_and_get_user pattern from the management API.

This eliminates the open redirect vulnerability (only authenticated
Astrolabe users can trigger the flow) and prevents unauthenticated
resource exhaustion via Login Flow v2 session creation.

The authenticated user_id from the token replaces the untrusted
user_id query parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:09:37 +02:00
Chris CoutinhoandClaude Opus 4.6 775bee83e3 fix: address PR review round 3 — info disclosure, conditional routes, cleanup
- Replace exception details in user-facing error page with generic message
- Only register /app/provision routes when enable_login_flow is true
- Piggyback expired provision session cleanup on hourly cleanup loop
- Add multi-process limitation comment on in-memory session store
- Add comment explaining login_url vs poll_endpoint rewrite asymmetry
- Document curl dependency in Dockerfile (healthcheck probes)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:37:42 +02:00
Chris CoutinhoandClaude Opus 4.6 2508f36ebf fix: address PR review round 2 — expiry checks, race guards, poll tests
- Log warning if /app mount not found when sharing poll task group
- Add docstring explaining unconditional task group creation
- Check session expires_at in provision_status to catch stale sessions
- Guard _poll_and_store status writes against cleanup-while-polling race
- Use "error" status (not "expired") when app_password is missing
- Remove hardcoded "Astrolabe Background Sync" user_agent string
- Fix async mock pattern (new_callable=AsyncMock) in test
- Add autouse fixture to clear _provision_sessions between tests
- Add _poll_and_store unit tests: completed, expired, error, cleanup
- Document all status values in provision_status docstring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 09:29:14 +02:00
Chris CoutinhoandClaude Opus 4.6 777a09c806 fix: address PR review — XSS escape, asyncio→anyio, URL rewrite dedup
- Escape HTML in _render_error to prevent XSS from exception messages
- Replace asyncio.create_task/sleep with anyio task group and sleep,
  tying poll task lifetime to the app lifespan for proper cleanup
- Extract rewrite_url_origin() utility to fix duplicated URL rewriting
  logic and replace urlparse._replace with stable urlunparse API
- Add warning log for insecure HTTP redirect URIs
- Add unit tests for validation, XSS escaping, route handlers, and
  URL rewriting (16 new tests in test_provision_routes.py)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:51:41 +02:00
Chris CoutinhoandClaude Opus 4.6 c2f23a566c fix: handle internal hostname without port in Login Flow v2 URL rewriting
Nextcloud may omit default ports in the login_url (e.g. http://app
instead of http://app:80). Extract just scheme+hostname from
NEXTCLOUD_HOST for the URL replacement check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 23:11:42 +02:00
Chris CoutinhoandClaude Opus 4.6 1a51f5bbf5 refactor: use redirect-based Login Flow v2 provision instead of popup
Replace the popup-based approach with a direct redirect to Nextcloud's
login page. This is more compatible with Playwright E2E tests and
simpler for users. The background polling task still runs server-side
to store the app password when the user grants access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:17:54 +02:00
Chris CoutinhoandClaude Opus 4.6 081ecbe401 feat: add web-based Login Flow v2 provisioning endpoint
Add /app/provision and /app/provision/status endpoints for browser-based
Login Flow v2 app password provisioning. Used by Astrolabe's "Enable
Semantic Search" to chain OAuth (bearer token) + Login Flow v2 (app
password) in a single user interaction.

The provision page initiates Login Flow v2, opens Nextcloud's login URL
in a popup, polls for completion via background task, and redirects back
to the caller's redirect_uri on success.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:56:16 +02:00