Misc fixes - #14
Open
rolandgeider wants to merge 7 commits into
Open
Conversation
_verify treated any JoseError as "the signing key may have rotated" and forced a fresh key-set fetch. Anyone can post a malformed or foreign-signed token, so an unauthenticated caller could drive one request to the IdP per attempt — the TTL cache never applied on the one path strangers reach. joserfc raises InvalidKeyIdError for an unknown key id and something else for a bad signature or a malformed token, and only the first can be fixed by fetching keys, so only it forces a refetch now. A kid is attacker-chosen though, so forced refetches are capped at one per minute, measured from the last forced one — measuring from the last fetch of any kind would let an ordinary refresh start the window and answer a rotation moments later with 401s. JwksCache also takes a lock, so concurrent misses share one fetch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The one-key sub-dicts ({"slot": {"id": ...}}) were a vestige of the full
objects trimmed in #13; every caller had to map ["slot_entry"]["id"] onto
the slot_entry_id parameter the follow-up tools take. The flat keys match
those parameter names, and the delete tools' responses, verbatim. A new
test pins the success shape, which nothing asserted on before.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Follow-ups from a full read-through of
src/wger_mcp, looking for duplication, overengineering and YAGNI. No structural changes — the layering holds. Two user-visible fixes, one hardening fix, and four refactors that remove repeated definitions rather than lines.Breaking (response shape)
Both are documented under Unreleased in the changelog:
add_exercise_with_setsreturns the ids flat (slot_id,slot_entry_id, …) instead of one-key sub-dicts. The flat keys match the parameter names the follow-up tools take, verbatim.lookup_food_by_barcode/lookup_foods_by_barcodesno longer returnwger_ingredient_payload. It repeatedmacros_per_100gunder a second set of keys, shaped for acreate_ingredientcall that cannot exist: wger's REST/ingredient/is read-only (the generated client has noingredient_createand noIngredientRequest), and the tool was removed with the move to multi-user auth. Every lookup was paying the caller's context for it.docs/HANDOFF.mdkept the payload as the seed of that tool should the endpoint ever appear; the note now says why it went instead.Fixes
ALLOWED_HOSTS=a,bin.envaborted startup with a parse error, because only the process environment was rewritten to the JSON form pydantic-settings parses — the dotenv file is a source of its own.NoDecodeplus a before-validator now handles both sources identically, andload_settings()no longer mutatesos.environas a side effect. The JSON spelling keeps working.JoseErrorcounted as "the key may have rotated", so an unauthenticated caller could drive one request to the IdP per malformed token. OnlyInvalidKeyIdErrorforces a refetch now, capped at one per minute and measured from the last forced refetch — measuring from the last fetch of any kind would answer a rotation with 401s until the window ran out.JwksCachealso takes a lock, so concurrent misses share one fetch.lookup_food_by_barcodegains the one-shot 429 retry the batch variant always had, as a consequence of the two sharing a fetch path.Refactors
opt_int/opt_uuid/opt_decimalreplaceopt(as_int(x, "x") if x is not None else None)at 38 call sites across six modules.day_bounds/day_range_filtersreplace three copies of the inclusive date-range translation. The exclusive upper bound is the kind of detail a fourth copy gets wrong, and getting it wrong drops the final day.METRICStable drives analytics' buckets, projection and deltas, which spelled the same mapping out three times.weekly_summaryandexercise_historynow accumulate through_accumulateinstead of open-codingreps * weighta second and third time.Verification
264 tests pass,
ruff checkclean. New tests cover the JWKS cache (6 cases, including that a rotation is still picked up immediately), the OFF lookup (4),day_bounds(4) and env-file list parsing (2).The two refactors that could silently change output were checked by dumping the real results before and after: every analytics tool's response over the same logs is byte-identical, metric subsets included, and so are the date filters all three affected tools send.
🤖 Generated with Claude Code