fix(kosync): serve the protocol endpoints at the paths KOReader requests - #1501
Open
thejdubb02 wants to merge 1 commit into
Open
fix(kosync): serve the protocol endpoints at the paths KOReader requests#1501thejdubb02 wants to merge 1 commit into
thejdubb02 wants to merge 1 commit into
Conversation
KOSync fixes its endpoints at the server root. A KOReader client configured with the CWA base URL requests /users/auth, but the handlers were only registered under /kosync/*, so that path fell through to web.books_list — whose `/<data>/<sort_param>/` rule matches it with data="users", sort_param="auth" — and its login requirement turned the request into a 302 to /login. That is the redirect in crocodilestick#1468, `next=%2Fusers%2Fauth%2F` and all. The authentication code was never the problem: authenticate_user() handles Basic Auth (and the reverse-proxy header) correctly. It was simply never reached. Registers the three protocol paths as additional rules on the same handlers, with strict_slashes=False so both /users/auth and /users/auth/ match — KOReader sends the trailing slash, and without this the generic browse rule still wins it. The existing /kosync/* paths are untouched, so clients pointed at that prefix keep working. Static rules outrank converter rules in Werkzeug, so the aliases take only the exact protocol paths; /series/new and /authors/stored/ still reach books_list. tests/unit/test_kosync_protocol_routes.py pins both halves. The x-auth-user/x-auth-key half of crocodilestick#1468 is deliberately not addressed here. That scheme authenticates with an MD5 of the password, and CWA stores werkzeug hashes, so supporting it means storing an additional credential per user — a schema and security decision that belongs with the maintainers rather than in a routing fix. Refs crocodilestick#1468
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #1468.
What is actually wrong
/users/authwas never a missing route — it was being swallowed by the generic browserule in
cps/web.py:/users/auth/matches it withdata="users",sort_param="auth", and the loginrequirement turns the request into a 302 to
/login—next=%2Fusers%2Fauth%2Fand all,exactly as reported.
The KOSync handlers were only registered under
/kosync/*, so a KOReader clientconfigured with the CWA base URL never reached them. The authentication code was not the
problem:
authenticate_user()handles Basic Auth and the reverse-proxy header correctly.It was simply never called.
The change
Three additional rules on the same three handlers, at the paths the protocol fixes.
strict_slashes=Falsematters here — KOReader sends the trailing slash, and without it/users/auth/is still won by the browse rule. The/kosync/*paths are untouched, soanyone pointed at that prefix keeps working.
Does this shadow anything?
No. Static rules outrank converter rules in Werkzeug, so the aliases take only the exact
protocol paths.
tests/unit/test_kosync_protocol_routes.pypins both halves: theprotocol paths reach KOSync, and
/series/new,/authors/stored/,/category/new,/publisher/storedstill reachbooks_list. The five protocol assertions fail onmasterand pass here; the browse assertions pass either way, which is the point ofhaving them.
Security
These handlers are
@csrf.exempt, so it is fair to ask whether exposing them at the rootwidens anything. It does not:
/kosync/users/authand/kosync/syncs/progress, already CSRF-exempt. This adds a path, not a capability.authenticate_user()reads credentials only from request headers — Basic Auth, or thereverse-proxy header when that is enabled. There is no session or cookie fallback, so
there are no ambient credentials for a cross-site request to ride. CSRF exemption is
correct for this endpoint and unaffected by where it is mounted.
answers with an endpoint that requires valid credentials.
Scope
The
x-auth-user/x-auth-keyhalf of #1468 is deliberately not addressed. That schemeauthenticates with an MD5 of the password, and CWA stores werkzeug hashes — supporting it
means storing an additional credential per user. That is a schema and security decision
that belongs with you, not in a routing fix. Happy to open a separate issue if useful.
Provenance
Written with AI assistance, then verified rather than trusted:
tests/unitis unchanged in aggregate — 63 failed / 21 errors on bothmasterand thisbranch (pre-existing, environment-dependent), with exactly +11 passing, which are the
new tests.
assumed.
above.