oscerd opened a new pull request, #28183:
URL: https://github.com/apache/camel/pull/28183
CAMEL-25887: `RestOpenApiEndpoint.loadSpecificationFrom()` parses the
specification with `setResolveFully(true)`, so swagger-parser loads every
external `$ref` when the consumer or producer is created: files from the
working directory and the classpath, and documents over http(s) when the
reference is a URL or the specification itself comes from a URL. The component
had no option to restrict this, and the component page did not mention it. The
same applies to `RestOpenApiReader` in camel-openapi-java, which parses the
contract of a contract-first REST DSL with `readContents(String)` (resolve on
by default) to serve it as api-doc.
## What
- **`externalReferences` option** on the `rest-openapi` endpoint and
component, and on the `openApi` element of the REST DSL (`OpenApiDefinition`,
passed to the consumer URI by `RestDefinition`):
- `all` (default, the current behaviour) allows any reference;
- `local` allows references to the classpath and the file system only; a
specification loaded from a URL may then reference no other document at all,
because the parser resolves its references against that URL;
- `none` allows only references inside the document.
- **The check runs before the parser resolves anything**, on the raw
JSON/YAML tree (`OpenApiExternalReferences`): every textual `$ref` is checked,
and under `local` the local documents the specification references are read
with the parser's own lookup (`RefUtils.readExternalRef`) and checked the same
way, so a remote reference inside a local sub-document is caught too. A
reference the option does not allow fails the consumer or producer creation
with a message that names the reference, its location in the document, and the
document. A specification loaded from a URL is read once
(`RemoteUrl.urlToString`, as `readLocation` does) and handed to
`readContents(content, null, options, location)`, so the default path is
unchanged and the restricted path fetches nothing else.
- **api-doc**: `RestOpenApiReader` applies the option of the `openApi`
element, or else the setting of the `rest-openapi` component (read through bean
introspection, since the modules do not depend on each other), so
`camel.component.rest-openapi.external-references=none` covers the contract
served as api-doc as well.
- The checker is a small package-private class that exists in both modules,
because neither camel-rest-openapi nor camel-openapi-java depends on the other
and adding such a dependency for it seemed wrong. Both copies say so.
- Docs: a section on the component page and on the contract-first page of
the user manual. No upgrade-guide entry, since the default keeps the current
behaviour.
## Why not swagger-parser's `setSafelyResolveURL`
It is not a "local only" mode: for an OpenAPI 3.0 document
`ResolverCache.loadRef()` runs the raw reference through
`PermittedUrlsChecker.verify()`, which rejects relative and file references
(multi-file specifications) and only lets through http(s) URLs that resolve to
public addresses or are on the allow list; for an OpenAPI 3.1 document only
`ReferenceVisitor.readHttp()` is gated; and a rejected reference only becomes a
parser message, which would need to be told apart from the other messages
CAMEL-25747 now logs.
## Tests
- `RestOpenApiExternalReferencesTest` (camel-rest-openapi): the default and
`local` resolve a classpath reference; `none` rejects a reference to another
document, in an OpenAPI 3.0 and a 3.1 document, and accepts a self-contained
one; `local` rejects an http reference without fetching it (WireMock sees no
request), finds a remote reference inside a referenced local document, and
rejects every external reference of a specification loaded from a URL (one
request for the root, none for the reference); the default resolves the
references of a remote specification; an unknown value is rejected; the
endpoint option and the component option both apply to the producer.
- `RestOpenApiReaderExternalReferencesTest` (camel-openapi-java): the
default resolves the referenced document into the api-doc; the `openApi`
element's `none` and the component's setting both fail the read.
- The existing tests of both modules pass.
## Noticed, not changed
`RestOpenApiSupport.getBasePathFromOasDocument()` (camel-openapi-java)
throws `IllegalArgumentException: URI is not absolute` for a contract without a
`servers` entry, because swagger-parser then adds a server with the url `/` and
`URI.create("/").toURL()` throws that, not the `MalformedURLException` the
method catches. CAMEL-24825 fixed the same symptom on the consumer side
(`RestOpenApiEndpoint`), but the api-doc of such a contract still fails. The
test contract here declares a server for that reason; the bug deserves its own
issue.
_Claude Code on behalf of oscerd_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]