fix(adapters): input-schema enforcement + header/cookie params (OAI-02, OAI-03, OAI-07, OAI-09)
- build_request takes the op's input_schema and rejects undeclared input keys (INVALID_INPUT) before any outbound request is built; explicit `additionalProperties: true` opts into catch-all input; non-object inputs rejected (OAI-02) - in: header parameters are stamped `wire: header` in the generated input schema and sent as upstream request headers, not query params; in: cookie fails import with a clear error (OAI-03) - a spec parameter named `body` is rejected at import unconditionally (OAI-07) - FromJsonSchema::new returns Result and validates method/path template/ base_url at construction; registered visibility forced to Internal like from_openapi; module doc corrected (OAI-09) Verified: cargo test, cargo test --all-features, clippy (both feature sets, -D warnings), cargo fmt --check
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: review-001-input-schema-enforcement
|
||||
name: Send exactly what the input schema advertises (OAI-02, OAI-03, OAI-07, OAI-09)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [review-001-openapi-import-integrity]
|
||||
scope: narrow
|
||||
risk: medium
|
||||
@@ -40,11 +40,11 @@ forwarder sends must match the contract `/schema` advertises:
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Undeclared input keys are rejected (or the pass-through is explicit config, tested) — peer input cannot add upstream query params (test)
|
||||
- [ ] `in: header` parameters send as headers; `in: cookie` errors clearly at import (tests)
|
||||
- [ ] `body`-named parameter collision handled loudly (test)
|
||||
- [ ] `from_jsonschema` validates method/path_template/base_url at construction; `Internal`-by-default matches `from_openapi` or the doc is corrected
|
||||
- [ ] `cargo test` and `cargo clippy --all-targets -- -D warnings` pass
|
||||
- [x] Undeclared input keys are rejected (or the pass-through is explicit config, tested) — peer input cannot add upstream query params (test)
|
||||
- [x] `in: header` parameters send as headers; `in: cookie` errors clearly at import (tests)
|
||||
- [x] `body`-named parameter collision handled loudly (test)
|
||||
- [x] `from_jsonschema` validates method/path_template/base_url at construction; `Internal`-by-default matches `from_openapi` or the doc is corrected
|
||||
- [x] `cargo test` and `cargo clippy --all-targets -- -D warnings` pass
|
||||
|
||||
## References
|
||||
|
||||
@@ -60,4 +60,43 @@ forwarder sends must match the contract `/schema` advertises:
|
||||
|
||||
## Summary
|
||||
|
||||
> Filled on completion.
|
||||
Forwarders now send exactly what the input schema advertises.
|
||||
|
||||
**OAI-02** (`forward.rs`): `build_request` takes the operation's
|
||||
`input_schema` and enforces it at call time — every input key must be
|
||||
declared in `properties` (path placeholders included; `from_openapi`
|
||||
declares them) or the input is rejected as `INVALID_INPUT` before any
|
||||
outbound request is built. An explicit `"additionalProperties": true`
|
||||
opts an operation into catch-all input (JSON Schema semantics — the
|
||||
schema advertises that extra keys are valid); non-object inputs are
|
||||
rejected. No pass-through knob: the review's preferred reject-undeclared
|
||||
posture is the behavior, documented in the module doc.
|
||||
|
||||
**OAI-03** (`forward.rs` + `from_openapi.rs`): the `Parameter.in_` field
|
||||
is no longer dead. `from_openapi` builds header-param properties as
|
||||
`{"wire": "header", "schema": …}` in the generated input schema;
|
||||
`build_request` routes marked properties into HTTP request headers
|
||||
(validated name/value, loud `INTERNAL` on refusal) instead of the query
|
||||
string. `in: cookie` fails import with a clear `SchemaParse` message
|
||||
(OAI-06's silent-degradation pattern avoided here).
|
||||
|
||||
**OAI-07** (`from_openapi.rs`): a spec parameter named `body` is rejected
|
||||
at import unconditionally (previously only when a requestBody coexisted)
|
||||
— the magic gateway body key would divert the declared parameter.
|
||||
|
||||
**OAI-09** (`from_jsonschema.rs`): `FromJsonSchema::new` now returns
|
||||
`Result` and validates at construction — method parses, path template
|
||||
placeholders are balanced and bound by the input schema, base URL is a
|
||||
userinfo-free http(s) URL — instead of surfacing `INTERNAL` on first
|
||||
invoke. The registered visibility is forced to `Internal` (ADR-015) like
|
||||
`from_openapi`; the module doc corrected (it previously claimed verbatim
|
||||
pass-through).
|
||||
|
||||
Integration note: `from_openapi`'s declaration-side checks
|
||||
(`unbound_placeholders`, collision rejection) now have a call-time
|
||||
counterpart; `to_openapi`'s gateway projection was untouched (its
|
||||
`CallRequest` shape passes through unchanged).
|
||||
|
||||
Verification: `cargo test` (297 lib), `cargo test --all-features` (368 +
|
||||
integration suites), `cargo clippy --all-targets -- -D warnings`
|
||||
(default + all features), `cargo fmt --check` — all green.
|
||||
Reference in New Issue
Block a user