Add logout() (POST /v1/logout) #39

Merged
mat merged 1 commit from feat/logout into main 2026-07-05 08:51:30 +00:00
Owner

Summary

Adds ComwattClient.logout() — a proper server-side logout, which the client was missing (only close() existed, and it explicitly does not log out).

  • POST /api/v1/logout — invalidates the cwt_session cookie server-side.
  • Clears the stored _username/_auth_hash so auto_reauth cannot silently re-establish the session on the next request (without this, the first call after logout() would resurrect the session).
  • Idempotent: a 401 (already logged out) is treated as a successful no-op; only unexpected statuses raise ComwattAPIError.
  • Orthogonal to close() (which only releases the local HTTP session, no network call).

Live verification (2026-07-05)

POST /api/v1/logout200 with empty body and Set-Cookie: cwt_session=; Expires=1970… (requests drops the cookie). GET /api/users/authenticated then returns 401. A second logout returns 401 (hence the idempotent handling).

Tests

  • test_logout_success — returns None, POSTs /v1/logout, clears credentials.
  • test_logout_idempotent_when_already_logged_out401 is a no-op.
  • test_logout_prevents_auto_reauth — after logout, a 401 is not silently re-authenticated.
  • test_logout_keeps_credentials_on_unexpected_error — credentials preserved on 500.

89 tests pass, mypy clean.

Opened as draft (WIP) — mark ready for review when you want.

## Summary Adds `ComwattClient.logout()` — a proper server-side logout, which the client was missing (only `close()` existed, and it explicitly does *not* log out). - `POST /api/v1/logout` — invalidates the `cwt_session` cookie server-side. - Clears the stored `_username`/`_auth_hash` so `auto_reauth` cannot silently re-establish the session on the next request (without this, the first call after `logout()` would resurrect the session). - **Idempotent**: a `401` (already logged out) is treated as a successful no-op; only unexpected statuses raise `ComwattAPIError`. - Orthogonal to `close()` (which only releases the local HTTP session, no network call). ## Live verification (2026-07-05) `POST /api/v1/logout` → `200` with empty body and `Set-Cookie: cwt_session=; Expires=1970…` (requests drops the cookie). `GET /api/users/authenticated` then returns `401`. A second logout returns `401` (hence the idempotent handling). ## Tests - `test_logout_success` — returns `None`, POSTs `/v1/logout`, clears credentials. - `test_logout_idempotent_when_already_logged_out` — `401` is a no-op. - `test_logout_prevents_auto_reauth` — after logout, a `401` is **not** silently re-authenticated. - `test_logout_keeps_credentials_on_unexpected_error` — credentials preserved on `500`. 89 tests pass, mypy clean. _Opened as draft (WIP) — mark ready for review when you want._
Add logout() (POST /v1/logout)
All checks were successful
Tests / forgejo-pytest (push) Successful in 43s
Tests / forgejo-pytest (pull_request) Successful in 42s
8472a2f09c
Logs the current session out server-side and clears the stored
credentials so auto_reauth can't silently restore the session on the
next request. Idempotent: a 401 (already logged out) is a no-op; only
unexpected statuses raise. Distinct from close(), which only releases
the local HTTP session.

Live-verified: POST /v1/logout returns 200 + expiring Set-Cookie, and
/users/authenticated then returns 401.
mat changed title from WIP: Add logout() (POST /v1/logout) to Add logout() (POST /v1/logout) 2026-07-05 08:51:10 +00:00
mat merged commit 202f2da903 into main 2026-07-05 08:51:30 +00:00
mat deleted branch feat/logout 2026-07-05 08:51:30 +00:00
mat referenced this pull request from a commit 2026-07-05 08:51:32 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mat/python-comwatt-client!39
No description provided.