This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/CAMEL-24298-siblings in repository https://gitbox.apache.org/repos/asf/camel.git
commit ad1e128743a78a27cbd9da5c197fc96e47c0b93d Author: Andrea Cosentino <[email protected]> AuthorDate: Wed Aug 5 15:31:33 2026 +0200 CAMEL-24298: extend the allowedSchemes allow-list to the sibling dynamic-URI EIPs Following the toD MVP (#25315), add the optional allowedSchemes allow-list to the remaining dynamic-URI EIPs: recipientList, routingSlip, dynamicRouter, enrich and pollEnrich. A resolved dynamic recipient whose scheme is not in the configured list is rejected. Enforcement is a shared ProcessorHelper.checkAllowedSchemes(...) called at each processor's recipient-resolution point: RoutingSlip (and DynamicRouter, which extends it), PollEnricher and RecipientListProcessor after prepareRecipient; enrich delegates to its internal SendDynamicProcessor which already enforces it. Default unset = any scheme allowed (no behavioural change). Because the check throws at the resolution point, a disallowed scheme follows each EIP's existing ignoreInvalidEndpoint semantics (hard-fail by default). Each of the 5 model definitions gets the allowedSchemes attribute + getter/setter + fluent builder, wired through its reifier. DynamicUriEipAllowedSchemesTest covers rejection across all five EIPs. Co-authored-by: Claude Opus 4.8 <[email protected]> --- .../apache/camel/catalog/models/dynamicRouter.json | 3 +- .../org/apache/camel/catalog/models/enrich.json | 3 +- .../apache/camel/catalog/models/pollEnrich.json | 3 +- .../apache/camel/catalog/models/recipientList.json | 3 +- .../apache/camel/catalog/models/routingSlip.json | 3 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 55 +++++++++++++ .../apache/camel/catalog/schemas/camel-xml-io.xsd | 55 +++++++++++++ .../org/apache/camel/model/dynamicRouter.json | 3 +- .../META-INF/org/apache/camel/model/enrich.json | 3 +- .../org/apache/camel/model/pollEnrich.json | 3 +- .../org/apache/camel/model/recipientList.json | 3 +- .../org/apache/camel/model/routingSlip.json | 3 +- .../camel/model/DynamicRouterDefinition.java | 28 +++++++ .../org/apache/camel/model/EnrichDefinition.java | 28 +++++++ .../apache/camel/model/PollEnrichDefinition.java | 28 +++++++ .../camel/model/RecipientListDefinition.java | 27 +++++++ .../apache/camel/model/RoutingSlipDefinition.java | 27 +++++++ .../java/org/apache/camel/processor/Enricher.java | 6 ++ .../org/apache/camel/processor/PollEnricher.java | 8 ++ .../apache/camel/processor/ProcessorHelper.java | 35 +++++++++ .../org/apache/camel/processor/RecipientList.java | 6 ++ .../camel/processor/RecipientListProcessor.java | 8 ++ .../org/apache/camel/processor/RoutingSlip.java | 8 ++ .../apache/camel/reifier/DynamicRouterReifier.java | 1 + .../org/apache/camel/reifier/EnrichReifier.java | 1 + .../apache/camel/reifier/PollEnrichReifier.java | 1 + .../apache/camel/reifier/RecipientListReifier.java | 1 + .../apache/camel/reifier/RoutingSlipReifier.java | 1 + .../processor/DynamicUriEipAllowedSchemesTest.java | 89 ++++++++++++++++++++++ .../apache/camel/java/out/JavaDslModelWriter.java | 5 ++ .../java/org/apache/camel/xml/in/ModelParser.java | 5 ++ .../java/org/apache/camel/xml/out/ModelWriter.java | 5 ++ .../org/apache/camel/yaml/out/YamlModelWriter.java | 5 ++ .../dsl/yaml/deserializers/ModelDeserializers.java | 30 ++++++++ .../resources/schema/camelYamlDsl-canonical.json | 25 ++++++ .../generated/resources/schema/camelYamlDsl.json | 25 ++++++ 36 files changed, 533 insertions(+), 10 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dynamicRouter.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dynamicRouter.json index 98bc59bd4c42..98cb7c7c56c9 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dynamicRouter.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dynamicRouter.json @@ -20,6 +20,7 @@ "expression": { "index": 4, "kind": "expression", "displayName": "Expression", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "jactl", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "variable", "wasm", "xpath", "xquery", "xtokenize" [...] "uriDelimiter": { "index": 5, "kind": "attribute", "displayName": "Uri Delimiter", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": ",", "description": "The delimiter used to separate endpoint URIs when the expression returns multiple endpoints. Default is comma." }, "ignoreInvalidEndpoints": { "index": 6, "kind": "attribute", "displayName": "Ignore Invalid Endpoints", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then invalid endpoint URIs are ignored and logged instead of throwing an exception." }, - "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." } + "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." }, + "allowedSchemes": { "index": 8, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is [...] } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json index 323e747b2a91..05039742fac6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json @@ -28,7 +28,8 @@ "cacheSize": { "index": 12, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, "ignoreInvalidEndpoint": { "index": 13, "kind": "attribute", "displayName": "Ignore Invalid Endpoint", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to ignore an invalid endpoint URI when trying to create a producer with that endpoint." }, "allowOptimisedComponents": { "index": 14, "kind": "attribute", "displayName": "Allow Optimised Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow components to optimise enricher if they are SendDynamicAware." }, - "autoStartComponents": { "index": 15, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when enricher is starting up." } + "autoStartComponents": { "index": 15, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when enricher is starting up." }, + "allowedSchemes": { "index": 16, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelToEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "To Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "Endpoint URI where this Exchange is being sent to" } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pollEnrich.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pollEnrich.json index f1f1185d0caf..e77f4ca81c10 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pollEnrich.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pollEnrich.json @@ -27,7 +27,8 @@ "cacheSize": { "index": 11, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ConsumerCache which is used to cache and reuse consumers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, "ignoreInvalidEndpoint": { "index": 12, "kind": "attribute", "displayName": "Ignore Invalid Endpoint", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to ignore an invalid endpoint URI when trying to create a consumer with that endpoint." }, "allowOptimisedComponents": { "index": 13, "kind": "attribute", "displayName": "Allow Optimised Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow components to optimise if they are PollDynamicAware." }, - "autoStartComponents": { "index": 14, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when poll enricher is starting up." } + "autoStartComponents": { "index": 14, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when poll enricher is starting up." }, + "allowedSchemes": { "index": 15, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelToEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "To Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "Endpoint URI where this Exchange is being sent to" } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/recipientList.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/recipientList.json index 7a226a4df1ac..35fd3d2d7768 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/recipientList.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/recipientList.json @@ -31,7 +31,8 @@ "streaming": { "index": 16, "kind": "attribute", "displayName": "Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then Camel will process replies out-of-order, eg in the order they come back. If disabled, Camel will process replies in the same order as defined by the recipient list." }, "onPrepare": { "index": 17, "kind": "attribute", "displayName": "On Prepare", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the exchange to be sent. This can be used to deep-clone messages that should be sent, or any custom logic needed before the exchange is sent." }, "cacheSize": { "index": 18, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, - "shareUnitOfWork": { "index": 19, "kind": "attribute", "displayName": "Share Unit Of Work", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This me [...] + "shareUnitOfWork": { "index": 19, "kind": "attribute", "displayName": "Share Unit Of Work", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This me [...] + "allowedSchemes": { "index": 20, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelRecipientListEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "Recipient List Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint uri of this recipient list" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routingSlip.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routingSlip.json index f792ad42c5ee..28c7302c2772 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routingSlip.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routingSlip.json @@ -19,7 +19,8 @@ "expression": { "index": 4, "kind": "expression", "displayName": "Expression", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "jactl", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "variable", "wasm", "xpath", "xquery", "xtokenize" [...] "uriDelimiter": { "index": 5, "kind": "attribute", "displayName": "Uri Delimiter", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": ",", "description": "The delimiter used to separate endpoint URIs in the routing slip expression. Default is comma." }, "ignoreInvalidEndpoints": { "index": 6, "kind": "attribute", "displayName": "Ignore Invalid Endpoints", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then invalid endpoint URIs are ignored and logged instead of throwing an exception." }, - "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." } + "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." }, + "allowedSchemes": { "index": 8, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is [...] }, "exchangeProperties": { "CamelSlipEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "Slip Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint uri of this routing slip" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index ee5fb9097f7d..1cd46566e4b4 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -5214,6 +5214,17 @@ If enabled then invalid endpoint URIs are ignored and logged instead of throwing <![CDATA[ Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching. +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -5358,6 +5369,17 @@ Whether to allow components to optimise enricher if they are SendDynamicAware. D <xs:documentation xml:lang="en"> <![CDATA[ Whether to auto startup components when enricher is starting up. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -11487,6 +11509,17 @@ Whether to allow components to optimise if they are PollDynamicAware. Default va <xs:documentation xml:lang="en"> <![CDATA[ Whether to auto startup components when poll enricher is starting up. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -11737,6 +11770,17 @@ for default cache size, or -1 to turn cache off. Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This means each sub exchange has its own individual unit of work. Default value: false +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -12605,6 +12649,17 @@ If enabled then invalid endpoint URIs are ignored and logged instead of throwing <![CDATA[ Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching. +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd index f7eeccaf7b22..3f8d4c70e701 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd @@ -4336,6 +4336,17 @@ If enabled then invalid endpoint URIs are ignored and logged instead of throwing <![CDATA[ Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching. +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -4480,6 +4491,17 @@ Whether to allow components to optimise enricher if they are SendDynamicAware. D <xs:documentation xml:lang="en"> <![CDATA[ Whether to auto startup components when enricher is starting up. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -10609,6 +10631,17 @@ Whether to allow components to optimise if they are PollDynamicAware. Default va <xs:documentation xml:lang="en"> <![CDATA[ Whether to auto startup components when poll enricher is starting up. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -10880,6 +10913,17 @@ for default cache size, or -1 to turn cache off. Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This means each sub exchange has its own individual unit of work. Default value: false +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> @@ -11748,6 +11792,17 @@ If enabled then invalid endpoint URIs are ignored and logged instead of throwing <![CDATA[ Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching. +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="allowedSchemes" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. +http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth +restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed. ]]> </xs:documentation> </xs:annotation> diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dynamicRouter.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dynamicRouter.json index 98bc59bd4c42..98cb7c7c56c9 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dynamicRouter.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dynamicRouter.json @@ -20,6 +20,7 @@ "expression": { "index": 4, "kind": "expression", "displayName": "Expression", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "jactl", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "variable", "wasm", "xpath", "xquery", "xtokenize" [...] "uriDelimiter": { "index": 5, "kind": "attribute", "displayName": "Uri Delimiter", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": ",", "description": "The delimiter used to separate endpoint URIs when the expression returns multiple endpoints. Default is comma." }, "ignoreInvalidEndpoints": { "index": 6, "kind": "attribute", "displayName": "Ignore Invalid Endpoints", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then invalid endpoint URIs are ignored and logged instead of throwing an exception." }, - "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." } + "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." }, + "allowedSchemes": { "index": 8, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is [...] } } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/enrich.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/enrich.json index 323e747b2a91..05039742fac6 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/enrich.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/enrich.json @@ -28,7 +28,8 @@ "cacheSize": { "index": 12, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, "ignoreInvalidEndpoint": { "index": 13, "kind": "attribute", "displayName": "Ignore Invalid Endpoint", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to ignore an invalid endpoint URI when trying to create a producer with that endpoint." }, "allowOptimisedComponents": { "index": 14, "kind": "attribute", "displayName": "Allow Optimised Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow components to optimise enricher if they are SendDynamicAware." }, - "autoStartComponents": { "index": 15, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when enricher is starting up." } + "autoStartComponents": { "index": 15, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when enricher is starting up." }, + "allowedSchemes": { "index": 16, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelToEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "To Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "Endpoint URI where this Exchange is being sent to" } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/pollEnrich.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/pollEnrich.json index f1f1185d0caf..e77f4ca81c10 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/pollEnrich.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/pollEnrich.json @@ -27,7 +27,8 @@ "cacheSize": { "index": 11, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ConsumerCache which is used to cache and reuse consumers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, "ignoreInvalidEndpoint": { "index": 12, "kind": "attribute", "displayName": "Ignore Invalid Endpoint", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to ignore an invalid endpoint URI when trying to create a consumer with that endpoint." }, "allowOptimisedComponents": { "index": 13, "kind": "attribute", "displayName": "Allow Optimised Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow components to optimise if they are PollDynamicAware." }, - "autoStartComponents": { "index": 14, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when poll enricher is starting up." } + "autoStartComponents": { "index": 14, "kind": "attribute", "displayName": "Auto Start Components", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to auto startup components when poll enricher is starting up." }, + "allowedSchemes": { "index": 15, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelToEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "To Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "Endpoint URI where this Exchange is being sent to" } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/recipientList.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/recipientList.json index 7a226a4df1ac..35fd3d2d7768 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/recipientList.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/recipientList.json @@ -31,7 +31,8 @@ "streaming": { "index": 16, "kind": "attribute", "displayName": "Streaming", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then Camel will process replies out-of-order, eg in the order they come back. If disabled, Camel will process replies in the same order as defined by the recipient list." }, "onPrepare": { "index": 17, "kind": "attribute", "displayName": "On Prepare", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the exchange to be sent. This can be used to deep-clone messages that should be sent, or any custom logic needed before the exchange is sent." }, "cacheSize": { "index": 18, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off." }, - "shareUnitOfWork": { "index": 19, "kind": "attribute", "displayName": "Share Unit Of Work", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This me [...] + "shareUnitOfWork": { "index": 19, "kind": "attribute", "displayName": "Share Unit Of Work", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This me [...] + "allowedSchemes": { "index": 20, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This i [...] }, "exchangeProperties": { "CamelRecipientListEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "Recipient List Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint uri of this recipient list" }, diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/routingSlip.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/routingSlip.json index f792ad42c5ee..28c7302c2772 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/routingSlip.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/routingSlip.json @@ -19,7 +19,8 @@ "expression": { "index": 4, "kind": "expression", "displayName": "Expression", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "jactl", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "variable", "wasm", "xpath", "xquery", "xtokenize" [...] "uriDelimiter": { "index": 5, "kind": "attribute", "displayName": "Uri Delimiter", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": ",", "description": "The delimiter used to separate endpoint URIs in the routing slip expression. Default is comma." }, "ignoreInvalidEndpoints": { "index": 6, "kind": "attribute", "displayName": "Ignore Invalid Endpoints", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If enabled then invalid endpoint URIs are ignored and logged instead of throwing an exception." }, - "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." } + "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching." }, + "allowedSchemes": { "index": 8, "kind": "attribute", "displayName": "Allowed Schemes", "group": "security", "label": "advanced,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is [...] }, "exchangeProperties": { "CamelSlipEndpoint": { "index": 0, "kind": "exchangeProperty", "displayName": "Slip Endpoint", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "autowired": false, "secret": false, "description": "The endpoint uri of this routing slip" }, diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/DynamicRouterDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/DynamicRouterDefinition.java index 0b93278e110e..b04e8c3cad78 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/DynamicRouterDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/DynamicRouterDefinition.java @@ -54,6 +54,13 @@ public class DynamicRouterDefinition<Type extends ProcessorDefinition<Type>> ext description = "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000." + " Set to -1 to turn off caching.") private String cacheSize; + @XmlAttribute + @Metadata(label = "advanced,security", + description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient" + + " may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the" + + " list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet" + + " deployments; by default (unset) any scheme is allowed.") + private String allowedSchemes; public DynamicRouterDefinition() { } @@ -63,6 +70,7 @@ public class DynamicRouterDefinition<Type extends ProcessorDefinition<Type>> ext this.uriDelimiter = source.uriDelimiter; this.ignoreInvalidEndpoints = source.ignoreInvalidEndpoints; this.cacheSize = source.cacheSize; + this.allowedSchemes = source.allowedSchemes; } public DynamicRouterDefinition(Expression expression) { @@ -124,6 +132,14 @@ public class DynamicRouterDefinition<Type extends ProcessorDefinition<Type>> ext return cacheSize; } + public String getAllowedSchemes() { + return allowedSchemes; + } + + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public void setCacheSize(String cacheSize) { this.cacheSize = cacheSize; } @@ -156,6 +172,18 @@ public class DynamicRouterDefinition<Type extends ProcessorDefinition<Type>> ext return this; } + /** + * Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. + * http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. By default (unset) any + * scheme is allowed. + * + * @return the builder + */ + public DynamicRouterDefinition<Type> allowedSchemes(String allowedSchemes) { + setAllowedSchemes(allowedSchemes); + return this; + } + /** * Sets the maximum size used by the {@link org.apache.camel.spi.ProducerCache} which is used to cache and reuse * producers when using this dynamic router, when uris are reused. diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java index efc6ad262ea7..165621ac2a63 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java @@ -90,6 +90,13 @@ public class EnrichDefinition extends ExpressionNode @Metadata(label = "advanced", defaultValue = "true", javaType = "java.lang.Boolean", description = "Whether to auto startup components when enricher is starting up.") private String autoStartComponents; + @XmlAttribute + @Metadata(label = "advanced,security", + description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient" + + " may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the" + + " list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet" + + " deployments; by default (unset) any scheme is allowed.") + private String allowedSchemes; public EnrichDefinition() { this((AggregationStrategy) null); @@ -113,6 +120,7 @@ public class EnrichDefinition extends ExpressionNode this.ignoreInvalidEndpoint = source.ignoreInvalidEndpoint; this.allowOptimisedComponents = source.allowOptimisedComponents; this.autoStartComponents = source.autoStartComponents; + this.allowedSchemes = source.allowedSchemes; } @Override @@ -168,6 +176,18 @@ public class EnrichDefinition extends ExpressionNode return this; } + /** + * Sets an optional comma-separated allow-list of component schemes that the dynamic resource may resolve to (e.g. + * http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. By default (unset) any + * scheme is allowed. + * + * @return the builder + */ + public EnrichDefinition allowedSchemes(String allowedSchemes) { + setAllowedSchemes(allowedSchemes); + return this; + } + /** * Refers to an AggregationStrategy to be used to merge the reply from the external service, into a single outgoing * message. By default Camel will use the reply from the external service as outgoing message. @@ -331,6 +351,14 @@ public class EnrichDefinition extends ExpressionNode this.aggregationStrategy = aggregationStrategy; } + public String getAllowedSchemes() { + return allowedSchemes; + } + + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { this.aggregationStrategyBean = aggregationStrategy; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java index 3f4982a77996..bb24f6401ddf 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java @@ -85,6 +85,13 @@ public class PollEnrichDefinition extends ExpressionNode @Metadata(label = "advanced", defaultValue = "true", javaType = "java.lang.Boolean", description = "Whether to auto startup components when poll enricher is starting up.") private String autoStartComponents; + @XmlAttribute + @Metadata(label = "advanced,security", + description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient" + + " may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the" + + " list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet" + + " deployments; by default (unset) any scheme is allowed.") + private String allowedSchemes; public PollEnrichDefinition() { } @@ -107,6 +114,7 @@ public class PollEnrichDefinition extends ExpressionNode this.ignoreInvalidEndpoint = source.ignoreInvalidEndpoint; this.allowOptimisedComponents = source.allowOptimisedComponents; this.autoStartComponents = source.autoStartComponents; + this.allowedSchemes = source.allowedSchemes; } @Override @@ -189,6 +197,18 @@ public class PollEnrichDefinition extends ExpressionNode return this; } + /** + * Sets an optional comma-separated allow-list of component schemes that the dynamic resource may resolve to (e.g. + * http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. By default (unset) any + * scheme is allowed. + * + * @return the builder + */ + public PollEnrichDefinition allowedSchemes(String allowedSchemes) { + setAllowedSchemes(allowedSchemes); + return this; + } + /** * Refers to an AggregationStrategy to be used to merge the reply from the external service, into a single outgoing * message. By default Camel will use the reply from the external service as outgoing message. @@ -370,6 +390,14 @@ public class PollEnrichDefinition extends ExpressionNode this.aggregationStrategy = aggregationStrategy; } + public String getAllowedSchemes() { + return allowedSchemes; + } + + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { this.aggregationStrategyBean = aggregationStrategy; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RecipientListDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RecipientListDefinition.java index 4adba6e218a2..02b3201f83cc 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RecipientListDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RecipientListDefinition.java @@ -109,6 +109,13 @@ public class RecipientListDefinition<Type extends ProcessorDefinition<Type>> ext @Metadata(label = "advanced", javaType = "java.lang.Boolean", description = "Shares the UnitOfWork with the parent and each of the sub messages. Recipient List will by default not share unit of work between the parent exchange and each recipient exchange. This means each sub exchange has its own individual unit of work.") private String shareUnitOfWork; + @XmlAttribute + @Metadata(label = "advanced,security", + description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient" + + " may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the" + + " list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet" + + " deployments; by default (unset) any scheme is allowed.") + private String allowedSchemes; public RecipientListDefinition() { } @@ -196,6 +203,18 @@ public class RecipientListDefinition<Type extends ProcessorDefinition<Type>> ext return this; } + /** + * Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. + * http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. By default (unset) any + * scheme is allowed. + * + * @return the builder + */ + public RecipientListDefinition<Type> allowedSchemes(String allowedSchemes) { + setAllowedSchemes(allowedSchemes); + return this; + } + /** * Sets a reference to the AggregationStrategy to be used to assemble the replies from the recipients, into a single * outgoing message from the RecipientList. By default Camel will use the last reply as the outgoing message. You @@ -576,6 +595,14 @@ public class RecipientListDefinition<Type extends ProcessorDefinition<Type>> ext this.delimiter = delimiter; } + public String getAllowedSchemes() { + return allowedSchemes; + } + + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public String getParallelProcessing() { return parallelProcessing; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutingSlipDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutingSlipDefinition.java index 6713ced55fc1..7f9b41b17031 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutingSlipDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutingSlipDefinition.java @@ -54,6 +54,13 @@ public class RoutingSlipDefinition<Type extends ProcessorDefinition<Type>> exten description = "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000." + " Set to -1 to turn off caching.") private String cacheSize; + @XmlAttribute + @Metadata(label = "advanced,security", + description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient" + + " may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the" + + " list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet" + + " deployments; by default (unset) any scheme is allowed.") + private String allowedSchemes; public RoutingSlipDefinition() { if (uriDelimiter == null) { @@ -128,6 +135,14 @@ public class RoutingSlipDefinition<Type extends ProcessorDefinition<Type>> exten return uriDelimiter; } + public String getAllowedSchemes() { + return allowedSchemes; + } + + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public void setIgnoreInvalidEndpoints(String ignoreInvalidEndpoints) { this.ignoreInvalidEndpoints = ignoreInvalidEndpoints; } @@ -193,6 +208,18 @@ public class RoutingSlipDefinition<Type extends ProcessorDefinition<Type>> exten return this; } + /** + * Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. + * http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. By default (unset) any + * scheme is allowed. + * + * @return the builder + */ + public RoutingSlipDefinition<Type> allowedSchemes(String allowedSchemes) { + setAllowedSchemes(allowedSchemes); + return this; + } + /** * Sets the maximum size used by the {@link org.apache.camel.spi.ProducerCache} which is used to cache and reuse * producers when using this routing slip, when uris are reused. diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java index fd8a0053061f..5ab1fa795b6d 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java @@ -72,6 +72,7 @@ public class Enricher extends BaseProcessorSupport private HeadersMapFactory headersMapFactory; private ProcessorExchangeFactory processorExchangeFactory; private SendDynamicProcessor sendDynamicProcessor; + private String allowedSchemes; public Enricher(Expression expression, String uri) { this.expression = expression; @@ -182,6 +183,10 @@ public class Enricher extends BaseProcessorSupport this.ignoreInvalidEndpoint = ignoreInvalidEndpoint; } + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public boolean isAllowOptimisedComponents() { return allowOptimisedComponents; } @@ -308,6 +313,7 @@ public class Enricher extends BaseProcessorSupport this.sendDynamicProcessor.setIgnoreInvalidEndpoint(ignoreInvalidEndpoint); this.sendDynamicProcessor.setAllowOptimisedComponents(allowOptimisedComponents); this.sendDynamicProcessor.setAutoStartupComponents(autoStartupComponents); + this.sendDynamicProcessor.setAllowedSchemes(allowedSchemes); this.sendDynamicProcessor.setVariableSend(variableSend); // create a per processor exchange factory diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java index a9e41d011393..3b007c702ab6 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java @@ -18,6 +18,7 @@ package org.apache.camel.processor; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.apache.camel.AggregationStrategy; import org.apache.camel.AsyncCallback; @@ -88,6 +89,7 @@ public class PollEnricher extends BaseProcessorSupport implements IdAware, Route private boolean aggregateOnException; private int cacheSize; private boolean ignoreInvalidEndpoint; + private Set<String> allowedSchemes; private boolean autoStartupComponents = true; private boolean allowOptimisedComponents = true; @@ -232,6 +234,10 @@ public class PollEnricher extends BaseProcessorSupport implements IdAware, Route this.ignoreInvalidEndpoint = ignoreInvalidEndpoint; } + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = ProcessorHelper.parseAllowedSchemes(allowedSchemes); + } + public boolean isAutoStartupComponents() { return autoStartupComponents; } @@ -297,6 +303,8 @@ public class PollEnricher extends BaseProcessorSupport implements IdAware, Route } Object targetRecipient = staticUri != null ? staticUri : recipient; targetRecipient = prepareRecipient(exchange, targetRecipient); + // enforce the optional allowed-schemes allow-list on the resolved dynamic recipient (CAMEL-24298) + ProcessorHelper.checkAllowedSchemes(allowedSchemes, targetRecipient); if (targetRecipient == null) { if (LOG.isDebugEnabled()) { LOG.debug("Poll dynamic evaluated as null so cannot poll from any endpoint"); diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ProcessorHelper.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ProcessorHelper.java index 2767cca7d38e..8d865ade6755 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ProcessorHelper.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ProcessorHelper.java @@ -17,14 +17,18 @@ package org.apache.camel.processor; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.NoTypeConversionAvailableException; +import org.apache.camel.ResolveEndpointFailedException; import org.apache.camel.spi.NormalizedEndpointUri; +import org.apache.camel.support.ExchangeHelper; import org.apache.camel.support.PatternHelper; import org.slf4j.MDC; @@ -33,6 +37,37 @@ final class ProcessorHelper { private ProcessorHelper() { } + /** + * Parses a comma-separated list of component schemes into a set, or {@code null} when unset. Used by the + * dynamic-uri EIPs to hold an optional {@code allowedSchemes} allow-list (see CAMEL-24298). + */ + static Set<String> parseAllowedSchemes(String allowedSchemes) { + if (allowedSchemes == null) { + return null; + } + Set<String> answer = new HashSet<>(); + for (String scheme : allowedSchemes.split(",")) { + answer.add(scheme.trim()); + } + return answer; + } + + /** + * Enforces the optional {@code allowedSchemes} allow-list on a resolved dynamic recipient: when the set is non-null + * and the recipient's scheme is not in it, a {@link ResolveEndpointFailedException} is thrown. A null set (the + * default) allows any scheme. + */ + static void checkAllowedSchemes(Set<String> allowedSchemes, Object recipient) { + if (allowedSchemes != null && recipient != null) { + String uri = recipient.toString(); + String scheme = ExchangeHelper.resolveScheme(uri); + if (scheme != null && !allowedSchemes.contains(scheme)) { + throw new ResolveEndpointFailedException( + uri, "Scheme " + scheme + " is not in the allowed schemes: " + allowedSchemes); + } + } + } + static Object prepareRecipient(Exchange exchange, Object recipient) throws NoTypeConversionAvailableException { if (recipient instanceof Endpoint || recipient instanceof NormalizedEndpointUri) { return recipient; diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientList.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientList.java index f593d25e3d11..476a0f338704 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientList.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientList.java @@ -61,6 +61,7 @@ public class RecipientList extends BaseProcessorSupport implements IdAware, Rout private final String delimiter; private boolean parallelProcessing; private boolean synchronous; + private String allowedSchemes; private boolean parallelAggregate; private boolean stopOnException; private boolean ignoreInvalidEndpoints; @@ -222,6 +223,7 @@ public class RecipientList extends BaseProcessorSupport implements IdAware, Rout recipientListProcessor.setErrorHandler(errorHandler); recipientListProcessor.setAggregateExecutorService(aggregateExecutorService); recipientListProcessor.setIgnoreInvalidEndpoints(isIgnoreInvalidEndpoints()); + recipientListProcessor.setAllowedSchemes(allowedSchemes); recipientListProcessor.setCacheSize(getCacheSize()); recipientListProcessor.setId(getId()); recipientListProcessor.setRouteId(getRouteId()); @@ -286,6 +288,10 @@ public class RecipientList extends BaseProcessorSupport implements IdAware, Rout this.synchronous = synchronous; } + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = allowedSchemes; + } + public boolean isParallelAggregate() { return parallelAggregate; } diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java index b052c03b09e5..4c4f1b253562 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; @@ -66,6 +67,7 @@ public class RecipientListProcessor extends MulticastProcessor { private boolean ignoreInvalidEndpoints; private final Expression expression; + private Set<String> allowedSchemes; private final String delimiter; private final ProducerCache producerCache; private int cacheSize; @@ -188,6 +190,10 @@ public class RecipientListProcessor extends MulticastProcessor { this.ignoreInvalidEndpoints = ignoreInvalidEndpoints; } + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = ProcessorHelper.parseAllowedSchemes(allowedSchemes); + } + @Override protected Iterable<ProcessorExchangePair> createProcessorExchangePairs(Exchange exchange) throws Exception { @@ -253,6 +259,8 @@ public class RecipientListProcessor extends MulticastProcessor { ExchangePattern pattern; try { recipient = prepareRecipient(exchange, recipient); + // enforce the optional allowed-schemes allow-list on the resolved dynamic recipient (CAMEL-24298) + ProcessorHelper.checkAllowedSchemes(allowedSchemes, recipient); Endpoint existing = getExistingEndpoint(exchange, recipient); if (existing == null) { endpoint = resolveEndpoint(exchange, recipient, prototype); diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RoutingSlip.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RoutingSlip.java index b0db8c50e378..a14b31e54c45 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RoutingSlip.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RoutingSlip.java @@ -17,6 +17,7 @@ package org.apache.camel.processor; import java.util.Iterator; +import java.util.Set; import org.apache.camel.AsyncCallback; import org.apache.camel.AsyncProcessor; @@ -71,6 +72,7 @@ public class RoutingSlip extends BaseProcessorSupport implements Traceable, IdAw protected String uriDelimiter; protected final CamelContext camelContext; protected AsyncProcessor errorHandler; + protected Set<String> allowedSchemes; /** * The iterator to be used for retrieving the next routing slip(s) to be used. @@ -176,6 +178,10 @@ public class RoutingSlip extends BaseProcessorSupport implements Traceable, IdAw this.errorHandler = errorHandler; } + public void setAllowedSchemes(String allowedSchemes) { + this.allowedSchemes = ProcessorHelper.parseAllowedSchemes(allowedSchemes); + } + @Override public String toString() { return id; @@ -257,6 +263,8 @@ public class RoutingSlip extends BaseProcessorSupport implements Traceable, IdAw try { Object recipient = iter.next(exchange); recipient = prepareRecipient(exchange, recipient); + // enforce the optional allowed-schemes allow-list on the resolved dynamic recipient (CAMEL-24298) + ProcessorHelper.checkAllowedSchemes(allowedSchemes, recipient); Endpoint existing = getExistingEndpoint(exchange, recipient); if (existing == null) { endpoint = resolveEndpoint(exchange, recipient, prototype); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java index 96c8fe2df7fe..4ea8e67b0700 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java @@ -45,6 +45,7 @@ public class DynamicRouterReifier extends ExpressionReifier<DynamicRouterDefinit if (num != null) { dynamicRouter.setCacheSize(num); } + dynamicRouter.setAllowedSchemes(parseString(definition.getAllowedSchemes())); AsyncProcessor errorHandler = (AsyncProcessor) wrapInErrorHandler(dynamicRouter.newRoutingSlipProcessorForErrorHandler()); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java index 47414d32c11d..086e3e6c25a5 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java @@ -65,6 +65,7 @@ public class EnrichReifier extends ExpressionReifier<EnrichDefinition> { enricher.setVariableReceive(parseString(definition.getVariableReceive())); enricher.setShareUnitOfWork(parseBoolean(definition.getShareUnitOfWork(), false)); enricher.setIgnoreInvalidEndpoint(parseBoolean(definition.getIgnoreInvalidEndpoint(), false)); + enricher.setAllowedSchemes(parseString(definition.getAllowedSchemes())); enricher.setAggregateOnException(parseBoolean(definition.getAggregateOnException(), false)); Integer num = parseInt(definition.getCacheSize()); if (num != null) { diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java index 79a245998974..bd1842cc74f8 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java @@ -81,6 +81,7 @@ public class PollEnrichReifier extends ProcessorReifier<PollEnrichDefinition> { } enricher.setVariableReceive(parseString(definition.getVariableReceive())); enricher.setIgnoreInvalidEndpoint(parseBoolean(definition.getIgnoreInvalidEndpoint(), false)); + enricher.setAllowedSchemes(parseString(definition.getAllowedSchemes())); enricher.setAggregateOnException(parseBoolean(definition.getAggregateOnException(), false)); if (definition.getAutoStartComponents() != null) { enricher.setAutoStartupComponents(parseBoolean(definition.getAutoStartComponents(), true)); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RecipientListReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RecipientListReifier.java index 6f7a4db173c3..08febd7be9cd 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RecipientListReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RecipientListReifier.java @@ -68,6 +68,7 @@ public class RecipientListReifier extends ProcessorReifier<RecipientListDefiniti answer.setShareUnitOfWork(isShareUnitOfWork); answer.setStopOnException(isStopOnException); answer.setIgnoreInvalidEndpoints(isIgnoreInvalidEndpoints); + answer.setAllowedSchemes(parseString(definition.getAllowedSchemes())); Integer num = parseInt(definition.getCacheSize()); if (num != null) { answer.setCacheSize(num); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java index ff9dc4cd239a..077a42afe24d 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java @@ -45,6 +45,7 @@ public class RoutingSlipReifier extends ExpressionReifier<RoutingSlipDefinition< if (definition.getIgnoreInvalidEndpoints() != null) { routingSlip.setIgnoreInvalidEndpoints(parseBoolean(definition.getIgnoreInvalidEndpoints(), false)); } + routingSlip.setAllowedSchemes(parseString(definition.getAllowedSchemes())); Integer num = parseInt(definition.getCacheSize()); if (num != null) { routingSlip.setCacheSize(num); diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/DynamicUriEipAllowedSchemesTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/DynamicUriEipAllowedSchemesTest.java new file mode 100644 index 000000000000..e366377204bd --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/processor/DynamicUriEipAllowedSchemesTest.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import org.apache.camel.CamelExecutionException; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.Header; +import org.apache.camel.ResolveEndpointFailedException; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * The optional {@code allowedSchemes} allow-list introduced on {@code toD} (CAMEL-24298) is also honoured by the + * sibling dynamic-uri EIPs: {@code recipientList}, {@code routingSlip}, {@code dynamicRouter}, {@code enrich} and + * {@code pollEnrich}. A resolved recipient whose scheme is not in the list is rejected. + */ +class DynamicUriEipAllowedSchemesTest extends ContextTestSupport { + + @Test + void recipientListRejectsDisallowedScheme() { + assertRejected("direct:rl"); + } + + @Test + void routingSlipRejectsDisallowedScheme() { + assertRejected("direct:rs"); + } + + @Test + void dynamicRouterRejectsDisallowedScheme() { + assertRejected("direct:dr"); + } + + @Test + void enrichRejectsDisallowedScheme() { + assertRejected("direct:en"); + } + + @Test + void pollEnrichRejectsDisallowedScheme() { + assertRejected("direct:pe"); + } + + private void assertRejected(String from) { + assertThatThrownBy(() -> template.sendBodyAndHeader(from, "Hello", "target", "seda:blocked")) + .isInstanceOf(CamelExecutionException.class) + .cause() + .isInstanceOf(ResolveEndpointFailedException.class) + .hasMessageContaining("not in the allowed schemes"); + } + + /** + * Dynamic router bean: routes to the header-supplied recipient on the first hop, then stops. + */ + public String slip(@Header("target") String target, @Header(Exchange.SLIP_ENDPOINT) String previous) { + return previous == null ? target : null; + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:rl").recipientList(header("target")).allowedSchemes("mock"); + from("direct:rs").routingSlip(header("target")).allowedSchemes("mock"); + from("direct:dr").dynamicRouter(method(DynamicUriEipAllowedSchemesTest.this, "slip")).allowedSchemes("mock"); + from("direct:en").enrich().simple("${header.target}").allowedSchemes("mock"); + from("direct:pe").pollEnrich().simple("${header.target}").allowedSchemes("mock").timeout(1000).end(); + } + }; + } +} diff --git a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java index cae1868f093d..e2721cac9660 100644 --- a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java +++ b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java @@ -1871,6 +1871,7 @@ public class JavaDslModelWriter extends JavaDslModelWriterSupport { doWriteAttribute(sb, "uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute(sb, "ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute(sb, "cacheSize", def.getCacheSize(), null); + doWriteAttribute(sb, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(sb, def); } protected void doWriteEnrichDefinition(StringBuilder sb, EnrichDefinition def) { @@ -1886,6 +1887,7 @@ public class JavaDslModelWriter extends JavaDslModelWriterSupport { doWriteAttribute(sb, "ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute(sb, "allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute(sb, "autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute(sb, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(sb, def); } protected void doWriteErrorHandlerDefinition(StringBuilder sb, ErrorHandlerDefinition def) { @@ -2212,6 +2214,7 @@ public class JavaDslModelWriter extends JavaDslModelWriterSupport { doWriteAttribute(sb, "ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute(sb, "allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute(sb, "autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute(sb, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(sb, def); } protected void doWriteProcessDefinition(StringBuilder sb, ProcessDefinition def) { @@ -2253,6 +2256,7 @@ public class JavaDslModelWriter extends JavaDslModelWriterSupport { doWriteAttribute(sb, "onPrepare", def.getOnPrepare(), null); doWriteAttribute(sb, "cacheSize", def.getCacheSize(), null); doWriteAttribute(sb, "shareUnitOfWork", def.getShareUnitOfWork(), null); + doWriteAttribute(sb, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(sb, def); } protected void doWriteRedeliveryPolicyDefinition(StringBuilder sb, RedeliveryPolicyDefinition def) { @@ -2446,6 +2450,7 @@ public class JavaDslModelWriter extends JavaDslModelWriterSupport { doWriteAttribute(sb, "uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute(sb, "ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute(sb, "cacheSize", def.getCacheSize(), null); + doWriteAttribute(sb, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(sb, def); } protected void doWriteSagaDefinition(StringBuilder sb, SagaDefinition def) { diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index 19c5adcb7258..44745bdfdcdd 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -373,6 +373,7 @@ public class ModelParser extends BaseParser { } protected DynamicRouterDefinition doParseDynamicRouterDefinition() throws IOException, XmlPullParserException { return doParse(new DynamicRouterDefinition(), (def, key, val) -> switch (key) { + case "allowedSchemes": def.setAllowedSchemes(val); yield true; case "cacheSize": def.setCacheSize(val); yield true; case "ignoreInvalidEndpoints": def.setIgnoreInvalidEndpoints(val); yield true; case "uriDelimiter": def.setUriDelimiter(val); yield true; @@ -386,6 +387,7 @@ public class ModelParser extends BaseParser { case "aggregationStrategyMethodAllowNull": def.setAggregationStrategyMethodAllowNull(val); yield true; case "aggregationStrategyMethodName": def.setAggregationStrategyMethodName(val); yield true; case "allowOptimisedComponents": def.setAllowOptimisedComponents(val); yield true; + case "allowedSchemes": def.setAllowedSchemes(val); yield true; case "autoStartComponents": def.setAutoStartComponents(val); yield true; case "cacheSize": def.setCacheSize(val); yield true; case "ignoreInvalidEndpoint": def.setIgnoreInvalidEndpoint(val); yield true; @@ -683,6 +685,7 @@ public class ModelParser extends BaseParser { case "aggregationStrategyMethodAllowNull": def.setAggregationStrategyMethodAllowNull(val); yield true; case "aggregationStrategyMethodName": def.setAggregationStrategyMethodName(val); yield true; case "allowOptimisedComponents": def.setAllowOptimisedComponents(val); yield true; + case "allowedSchemes": def.setAllowedSchemes(val); yield true; case "autoStartComponents": def.setAutoStartComponents(val); yield true; case "cacheSize": def.setCacheSize(val); yield true; case "ignoreInvalidEndpoint": def.setIgnoreInvalidEndpoint(val); yield true; @@ -728,6 +731,7 @@ public class ModelParser extends BaseParser { case "aggregationStrategy": def.setAggregationStrategy(val); yield true; case "aggregationStrategyMethodAllowNull": def.setAggregationStrategyMethodAllowNull(val); yield true; case "aggregationStrategyMethodName": def.setAggregationStrategyMethodName(val); yield true; + case "allowedSchemes": def.setAllowedSchemes(val); yield true; case "cacheSize": def.setCacheSize(val); yield true; case "delimiter": def.setDelimiter(val); yield true; case "executorService": def.setExecutorService(val); yield true; @@ -1062,6 +1066,7 @@ public class ModelParser extends BaseParser { } protected RoutingSlipDefinition doParseRoutingSlipDefinition() throws IOException, XmlPullParserException { return doParse(new RoutingSlipDefinition(), (def, key, val) -> switch (key) { + case "allowedSchemes": def.setAllowedSchemes(val); yield true; case "cacheSize": def.setCacheSize(val); yield true; case "ignoreInvalidEndpoints": def.setIgnoreInvalidEndpoints(val); yield true; case "uriDelimiter": def.setUriDelimiter(val); yield true; diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 1b949e1a840c..d848dc156bf0 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -956,6 +956,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute("cacheSize", def.getCacheSize(), null); + doWriteAttribute("allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(def); endElement(name); } @@ -973,6 +974,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute("allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute("autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute("allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(def); endElement(name); } @@ -1375,6 +1377,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute("allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute("autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute("allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(def); endElement(name); } @@ -1428,6 +1431,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("onPrepare", def.getOnPrepare(), null); doWriteAttribute("cacheSize", def.getCacheSize(), null); doWriteAttribute("shareUnitOfWork", def.getShareUnitOfWork(), null); + doWriteAttribute("allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(def); endElement(name); } @@ -1669,6 +1673,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute("ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute("cacheSize", def.getCacheSize(), null); + doWriteAttribute("allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(def); endElement(name); } diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java index 460305fcbcba..2837cbeea4d2 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java @@ -951,6 +951,7 @@ public class YamlModelWriter extends YamlModelWriterSupport { doWriteAttribute(jo, "uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute(jo, "ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute(jo, "cacheSize", def.getCacheSize(), null); + doWriteAttribute(jo, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(jo, def); return jo; } @@ -968,6 +969,7 @@ public class YamlModelWriter extends YamlModelWriterSupport { doWriteAttribute(jo, "ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute(jo, "allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute(jo, "autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute(jo, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(jo, def); return jo; } @@ -1370,6 +1372,7 @@ public class YamlModelWriter extends YamlModelWriterSupport { doWriteAttribute(jo, "ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint(), null); doWriteAttribute(jo, "allowOptimisedComponents", def.getAllowOptimisedComponents(), "true"); doWriteAttribute(jo, "autoStartComponents", def.getAutoStartComponents(), "true"); + doWriteAttribute(jo, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(jo, def); return jo; } @@ -1423,6 +1426,7 @@ public class YamlModelWriter extends YamlModelWriterSupport { doWriteAttribute(jo, "onPrepare", def.getOnPrepare(), null); doWriteAttribute(jo, "cacheSize", def.getCacheSize(), null); doWriteAttribute(jo, "shareUnitOfWork", def.getShareUnitOfWork(), null); + doWriteAttribute(jo, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(jo, def); return jo; } @@ -1665,6 +1669,7 @@ public class YamlModelWriter extends YamlModelWriterSupport { doWriteAttribute(jo, "uriDelimiter", def.getUriDelimiter(), ","); doWriteAttribute(jo, "ignoreInvalidEndpoints", def.getIgnoreInvalidEndpoints(), null); doWriteAttribute(jo, "cacheSize", def.getCacheSize(), null); + doWriteAttribute(jo, "allowedSchemes", def.getAllowedSchemes(), null); doWriteExpressionNodeElements(jo, def); return jo; } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 50b7c6e090a6..6a183fc53af1 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -4725,6 +4725,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { deprecated = false, properties = { @YamlProperty(name = "__extends", type = "object:org.apache.camel.model.language.ExpressionDefinition", oneOf = "expression"), + @YamlProperty(name = "allowedSchemes", type = "string", description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed.", displayName = "Allowed Schemes"), @YamlProperty(name = "cacheSize", type = "number", description = "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching.", displayName = "Cache Size"), @YamlProperty(name = "description", type = "string", description = "The description for this node", displayName = "Description"), @YamlProperty(name = "disabled", type = "boolean", defaultValue = "false", description = "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime.", displayName = "Disabled"), @@ -4750,6 +4751,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { String propertyName, Node node) { propertyKey = org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey); switch(propertyKey) { + case "allowedSchemes": { + String val = asText(node); + target.setAllowedSchemes(val); + break; + } case "cacheSize": { String val = asText(node); target.setCacheSize(val); @@ -4941,6 +4947,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "aggregationStrategyMethodAllowNull", type = "string", description = "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Allow Null"), @YamlProperty(name = "aggregationStrategyMethodName", type = "string", description = "This option can be used to explicitly declare the method name to use, when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Name"), @YamlProperty(name = "allowOptimisedComponents", type = "boolean", defaultValue = "true", description = "Whether to allow components to optimise enricher if they are SendDynamicAware.", displayName = "Allow Optimised Components"), + @YamlProperty(name = "allowedSchemes", type = "string", description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed.", displayName = "Allowed Schemes"), @YamlProperty(name = "autoStartComponents", type = "boolean", defaultValue = "true", description = "Whether to auto startup components when enricher is starting up.", displayName = "Auto Start Components"), @YamlProperty(name = "cacheSize", type = "number", description = "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off.", displayName = "Cache Size"), @YamlProperty(name = "description", type = "string", description = "The description for this node", displayName = "Description"), @@ -4994,6 +5001,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setAllowOptimisedComponents(val); break; } + case "allowedSchemes": { + String val = asText(node); + target.setAllowedSchemes(val); + break; + } case "autoStartComponents": { String val = asText(node); target.setAutoStartComponents(val); @@ -12074,6 +12086,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "aggregationStrategyMethodAllowNull", type = "string", description = "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Allow Null"), @YamlProperty(name = "aggregationStrategyMethodName", type = "string", description = "This option can be used to explicitly declare the method name to use, when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Name"), @YamlProperty(name = "allowOptimisedComponents", type = "boolean", defaultValue = "true", description = "Whether to allow components to optimise if they are PollDynamicAware.", displayName = "Allow Optimised Components"), + @YamlProperty(name = "allowedSchemes", type = "string", description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed.", displayName = "Allowed Schemes"), @YamlProperty(name = "autoStartComponents", type = "boolean", defaultValue = "true", description = "Whether to auto startup components when poll enricher is starting up.", displayName = "Auto Start Components"), @YamlProperty(name = "cacheSize", type = "number", description = "Sets the maximum size used by the ConsumerCache which is used to cache and reuse consumers when uris are reused. Use 0 for default cache size, or -1 to turn cache off.", displayName = "Cache Size"), @YamlProperty(name = "description", type = "string", description = "The description for this node", displayName = "Description"), @@ -12126,6 +12139,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setAllowOptimisedComponents(val); break; } + case "allowedSchemes": { + String val = asText(node); + target.setAllowedSchemes(val); + break; + } case "autoStartComponents": { String val = asText(node); target.setAutoStartComponents(val); @@ -13034,6 +13052,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "aggregationStrategy", type = "string", description = "Sets the AggregationStrategy to be used to assemble the replies from the recipients, into a single outgoing message.", displayName = "Aggregation Strategy"), @YamlProperty(name = "aggregationStrategyMethodAllowNull", type = "boolean", defaultValue = "false", description = "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Allow Null"), @YamlProperty(name = "aggregationStrategyMethodName", type = "string", description = "This option can be used to explicitly declare the method name to use, when using POJOs as the AggregationStrategy.", displayName = "Aggregation Strategy Method Name"), + @YamlProperty(name = "allowedSchemes", type = "string", description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed.", displayName = "Allowed Schemes"), @YamlProperty(name = "cacheSize", type = "number", description = "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers when uris are reused. Use 0 for default cache size, or -1 to turn cache off.", displayName = "Cache Size"), @YamlProperty(name = "delimiter", type = "string", defaultValue = ",", description = "Delimiter used if the Expression returned multiple endpoints. Can be turned off using the value false.", displayName = "Delimiter"), @YamlProperty(name = "description", type = "string", description = "The description for this node", displayName = "Description"), @@ -13083,6 +13102,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setAggregationStrategyMethodName(val); break; } + case "allowedSchemes": { + String val = asText(node); + target.setAllowedSchemes(val); + break; + } case "cacheSize": { String val = asText(node); target.setCacheSize(val); @@ -15550,6 +15574,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { deprecated = false, properties = { @YamlProperty(name = "__extends", type = "object:org.apache.camel.model.language.ExpressionDefinition", oneOf = "expression"), + @YamlProperty(name = "allowedSchemes", type = "string", description = "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed.", displayName = "Allowed Schemes"), @YamlProperty(name = "cacheSize", type = "number", description = "Configures the cache size for ProducerCache which caches producers for reuse. The default cache size is 1000. Set to -1 to turn off caching.", displayName = "Cache Size"), @YamlProperty(name = "description", type = "string", description = "The description for this node", displayName = "Description"), @YamlProperty(name = "disabled", type = "boolean", defaultValue = "false", description = "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime.", displayName = "Disabled"), @@ -15580,6 +15605,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { String propertyName, Node node) { propertyKey = org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey); switch(propertyKey) { + case "allowedSchemes": { + String val = asText(node); + target.setAllowedSchemes(val); + break; + } case "cacheSize": { String val = asText(node); target.setCacheSize(val); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json index 3f82b7efc540..13dbe0c2b152 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json @@ -1145,6 +1145,11 @@ "type" : "object", "additionalProperties" : false, "properties" : { + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size", @@ -1223,6 +1228,11 @@ "description" : "Whether to allow components to optimise enricher if they are SendDynamicAware.", "default" : true }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "autoStartComponents" : { "type" : "boolean", "title" : "Auto Start Components", @@ -2961,6 +2971,11 @@ "description" : "Whether to allow components to optimise if they are PollDynamicAware.", "default" : true }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "autoStartComponents" : { "type" : "boolean", "title" : "Auto Start Components", @@ -3112,6 +3127,11 @@ "title" : "Aggregation Strategy Method Name", "description" : "This option can be used to explicitly declare the method name to use, when using POJOs as the AggregationStrategy." }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size", @@ -4158,6 +4178,11 @@ "type" : "object", "additionalProperties" : false, "properties" : { + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size", diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index 72766d7318fa..76a9d85c2cd9 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -1381,6 +1381,11 @@ } ] } ], "properties" : { + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size", @@ -1557,6 +1562,11 @@ "description" : "Whether to allow components to optimise enricher if they are SendDynamicAware.", "default" : true }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "autoStartComponents" : { "type" : "boolean", "title" : "Auto Start Components", @@ -4537,6 +4547,11 @@ "description" : "Whether to allow components to optimise if they are PollDynamicAware.", "default" : true }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "autoStartComponents" : { "type" : "boolean", "title" : "Auto Start Components", @@ -4882,6 +4897,11 @@ "title" : "Aggregation Strategy Method Name", "description" : "This option can be used to explicitly declare the method name to use, when using POJOs as the AggregationStrategy." }, + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size", @@ -6186,6 +6206,11 @@ } ] } ], "properties" : { + "allowedSchemes" : { + "type" : "string", + "title" : "Allowed Schemes", + "description" : "Sets an optional comma-separated allow-list of component schemes that the dynamic recipient may resolve to (e.g. http,https). When set, a dynamic endpoint whose scheme is not in the list is rejected. This is a defence-in-depth restriction, useful for low-code / Kamelet deployments; by default (unset) any scheme is allowed." + }, "cacheSize" : { "type" : "number", "title" : "Cache Size",
