This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 70469a817b0229590292f4dbc84ecb410b042479 Author: Claus Ibsen <[email protected]> AuthorDate: Tue May 5 15:48:29 2020 +0200 CAMEL-15013: Template components - Add option to turn on|off allow using header with override template --- .../component/mvel/MvelComponentConfigurer.java | 5 +++ .../component/mvel/MvelEndpointConfigurer.java | 5 +++ .../org/apache/camel/component/mvel/mvel.json | 2 ++ .../camel-mvel/src/main/docs/mvel-component.adoc | 6 ++-- .../apache/camel/component/mvel/MvelComponent.java | 22 ++++++++++++- .../apache/camel/component/mvel/MvelEndpoint.java | 38 +++++++++++++++++----- .../camel/language/mvel/MvelComponentTest.java | 7 ++-- .../component/dsl/MvelComponentBuilderFactory.java | 18 ++++++++++ .../endpoint/dsl/MvelEndpointBuilderFactory.java | 34 +++++++++++++++++++ 9 files changed, 124 insertions(+), 13 deletions(-) diff --git a/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelComponentConfigurer.java b/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelComponentConfigurer.java index 747149c..6ce6fe7 100644 --- a/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelComponentConfigurer.java +++ b/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelComponentConfigurer.java @@ -19,6 +19,8 @@ public class MvelComponentConfigurer extends PropertyConfigurerSupport implement public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { MvelComponent target = (MvelComponent) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "allowtemplatefromheader": + case "allowTemplateFromHeader": target.setAllowTemplateFromHeader(property(camelContext, boolean.class, value)); return true; case "basicpropertybinding": case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true; case "lazystartproducer": @@ -30,6 +32,7 @@ public class MvelComponentConfigurer extends PropertyConfigurerSupport implement @Override public Map<String, Object> getAllOptions(Object target) { Map<String, Object> answer = new CaseInsensitiveMap(); + answer.put("allowTemplateFromHeader", boolean.class); answer.put("basicPropertyBinding", boolean.class); answer.put("lazyStartProducer", boolean.class); return answer; @@ -39,6 +42,8 @@ public class MvelComponentConfigurer extends PropertyConfigurerSupport implement public Object getOptionValue(Object obj, String name, boolean ignoreCase) { MvelComponent target = (MvelComponent) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "allowtemplatefromheader": + case "allowTemplateFromHeader": return target.isAllowTemplateFromHeader(); case "basicpropertybinding": case "basicPropertyBinding": return target.isBasicPropertyBinding(); case "lazystartproducer": diff --git a/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelEndpointConfigurer.java b/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelEndpointConfigurer.java index 456c532..e29d69b 100644 --- a/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelEndpointConfigurer.java +++ b/components/camel-mvel/src/generated/java/org/apache/camel/component/mvel/MvelEndpointConfigurer.java @@ -19,6 +19,8 @@ public class MvelEndpointConfigurer extends PropertyConfigurerSupport implements public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { MvelEndpoint target = (MvelEndpoint) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "allowtemplatefromheader": + case "allowTemplateFromHeader": target.setAllowTemplateFromHeader(property(camelContext, boolean.class, value)); return true; case "basicpropertybinding": case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true; case "contentcache": @@ -34,6 +36,7 @@ public class MvelEndpointConfigurer extends PropertyConfigurerSupport implements @Override public Map<String, Object> getAllOptions(Object target) { Map<String, Object> answer = new CaseInsensitiveMap(); + answer.put("allowTemplateFromHeader", boolean.class); answer.put("basicPropertyBinding", boolean.class); answer.put("contentCache", boolean.class); answer.put("encoding", java.lang.String.class); @@ -46,6 +49,8 @@ public class MvelEndpointConfigurer extends PropertyConfigurerSupport implements public Object getOptionValue(Object obj, String name, boolean ignoreCase) { MvelEndpoint target = (MvelEndpoint) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "allowtemplatefromheader": + case "allowTemplateFromHeader": return target.isAllowTemplateFromHeader(); case "basicpropertybinding": case "basicPropertyBinding": return target.isBasicPropertyBinding(); case "contentcache": diff --git a/components/camel-mvel/src/generated/resources/org/apache/camel/component/mvel/mvel.json b/components/camel-mvel/src/generated/resources/org/apache/camel/component/mvel/mvel.json index aa5795c..c7fea8d 100644 --- a/components/camel-mvel/src/generated/resources/org/apache/camel/component/mvel/mvel.json +++ b/components/camel-mvel/src/generated/resources/org/apache/camel/component/mvel/mvel.json @@ -21,11 +21,13 @@ "lenientProperties": false }, "componentProperties": { + "allowTemplateFromHeader": { "kind": "property", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the he [...] "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the r [...] "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" } }, "properties": { "resourceUri": { "kind": "path", "displayName": "Resource Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "description": "Path to the resource. You can prefix with: classpath, file, http, ref, or bean. classpath, file and http loads the resource using these protocols (classpath is default). ref will lookup the resource in the registry. bean will call a method on a [...] + "allowTemplateFromHeader": { "kind": "parameter", "displayName": "Allow Template From Header", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "description": "Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the h [...] "contentCache": { "kind": "parameter", "displayName": "Content Cache", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "description": "Sets whether to use resource content cache or not" }, "encoding": { "kind": "parameter", "displayName": "Encoding", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Character encoding of the resource content." }, "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the [...] diff --git a/components/camel-mvel/src/main/docs/mvel-component.adoc b/components/camel-mvel/src/main/docs/mvel-component.adoc index cc0cb2e..f1258aa 100644 --- a/components/camel-mvel/src/main/docs/mvel-component.adoc +++ b/components/camel-mvel/src/main/docs/mvel-component.adoc @@ -46,13 +46,14 @@ You can append query options to the URI in the following format, // component options: START -The MVEL component supports 2 options, which are listed below. +The MVEL component supports 3 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== | Name | Description | Default | Type +| *allowTemplateFromHeader* (producer) | Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care. | false | boolean | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...] | *basicPropertyBinding* (advanced) | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean |=== @@ -80,12 +81,13 @@ with the following path and query parameters: |=== -=== Query Parameters (5 parameters): +=== Query Parameters (6 parameters): [width="100%",cols="2,5,^1,2",options="header"] |=== | Name | Description | Default | Type +| *allowTemplateFromHeader* (producer) | Whether to allow to use resource template from header or not (default false). Enabling this allows to specify dynamic templates via message header. However this can be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care. | false | boolean | *contentCache* (producer) | Sets whether to use resource content cache or not | false | boolean | *encoding* (producer) | Character encoding of the resource content. | | String | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...] diff --git a/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelComponent.java b/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelComponent.java index a1399b6..d82e16b 100644 --- a/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelComponent.java +++ b/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelComponent.java @@ -19,6 +19,7 @@ package org.apache.camel.component.mvel; import java.util.Map; import org.apache.camel.Endpoint; +import org.apache.camel.spi.Metadata; import org.apache.camel.spi.annotations.Component; import org.apache.camel.support.DefaultComponent; import org.apache.camel.support.ResourceHelper; @@ -30,6 +31,9 @@ import org.apache.camel.support.ResourceHelper; @Component("mvel") public class MvelComponent extends DefaultComponent { + @Metadata(defaultValue = "false") + private boolean allowTemplateFromHeader; + public MvelComponent() { } @@ -38,8 +42,10 @@ public class MvelComponent extends DefaultComponent { boolean cache = getAndRemoveParameter(parameters, "contentCache", Boolean.class, Boolean.TRUE); MvelEndpoint answer = new MvelEndpoint(uri, this, remaining); - setProperties(answer, parameters); answer.setContentCache(cache); + answer.setAllowTemplateFromHeader(allowTemplateFromHeader); + + setProperties(answer, parameters); // if its a http resource then append any remaining parameters and update the resource uri if (ResourceHelper.isHttpUri(remaining)) { @@ -50,4 +56,18 @@ public class MvelComponent extends DefaultComponent { return answer; } + public boolean isAllowTemplateFromHeader() { + return allowTemplateFromHeader; + } + + /** + * Whether to allow to use resource template from header or not (default false). + * + * Enabling this allows to specify dynamic templates via message header. However this can + * be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care. + */ + public void setAllowTemplateFromHeader(boolean allowTemplateFromHeader) { + this.allowTemplateFromHeader = allowTemplateFromHeader; + } + } diff --git a/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelEndpoint.java b/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelEndpoint.java index f41a15b..ee330c8 100644 --- a/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelEndpoint.java +++ b/components/camel-mvel/src/main/java/org/apache/camel/component/mvel/MvelEndpoint.java @@ -40,8 +40,11 @@ import org.mvel2.templates.TemplateRuntime; @UriEndpoint(firstVersion = "2.12.0", scheme = "mvel", title = "MVEL", syntax = "mvel:resourceUri", producerOnly = true, label = "transformation,script") public class MvelEndpoint extends ResourceEndpoint { + @UriParam(defaultValue = "false") + private boolean allowTemplateFromHeader; @UriParam private String encoding; + private volatile String template; private volatile CompiledTemplate compiled; @@ -59,6 +62,20 @@ public class MvelEndpoint extends ResourceEndpoint { return "mvel:" + getResourceUri(); } + public boolean isAllowTemplateFromHeader() { + return allowTemplateFromHeader; + } + + /** + * Whether to allow to use resource template from header or not (default false). + * + * Enabling this allows to specify dynamic templates via message header. However this can + * be seen as a potential security vulnerability if the header is coming from a malicious user, so use this with care. + */ + public void setAllowTemplateFromHeader(boolean allowTemplateFromHeader) { + this.allowTemplateFromHeader = allowTemplateFromHeader; + } + public String getEncoding() { return encoding; } @@ -75,21 +92,26 @@ public class MvelEndpoint extends ResourceEndpoint { String path = getResourceUri(); ObjectHelper.notNull(path, "resourceUri"); - String newResourceUri = exchange.getIn().getHeader(MvelConstants.MVEL_RESOURCE_URI, String.class); - if (newResourceUri != null) { - exchange.getIn().removeHeader(MvelConstants.MVEL_RESOURCE_URI); + if (allowTemplateFromHeader) { + String newResourceUri = exchange.getIn().getHeader(MvelConstants.MVEL_RESOURCE_URI, String.class); + if (newResourceUri != null) { + exchange.getIn().removeHeader(MvelConstants.MVEL_RESOURCE_URI); - log.debug("{} set to {} creating new endpoint to handle exchange", MvelConstants.MVEL_RESOURCE_URI, newResourceUri); - MvelEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri); - newEndpoint.onExchange(exchange); - return; + log.debug("{} set to {} creating new endpoint to handle exchange", MvelConstants.MVEL_RESOURCE_URI, newResourceUri); + MvelEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri); + newEndpoint.onExchange(exchange); + return; + } } CompiledTemplate compiled; ParserContext mvelContext = ParserContext.create(); Map<String, Object> variableMap = ExchangeHelper.createVariableMap(exchange); - String content = exchange.getIn().getHeader(MvelConstants.MVEL_TEMPLATE, String.class); + String content = null; + if (allowTemplateFromHeader) { + content = exchange.getIn().getHeader(MvelConstants.MVEL_TEMPLATE, String.class); + } if (content != null) { // use content from header if (log.isDebugEnabled()) { diff --git a/components/camel-mvel/src/test/java/org/apache/camel/language/mvel/MvelComponentTest.java b/components/camel-mvel/src/test/java/org/apache/camel/language/mvel/MvelComponentTest.java index bdf10cd..da75b9d 100644 --- a/components/camel-mvel/src/test/java/org/apache/camel/language/mvel/MvelComponentTest.java +++ b/components/camel-mvel/src/test/java/org/apache/camel/language/mvel/MvelComponentTest.java @@ -41,7 +41,7 @@ public class MvelComponentTest extends CamelTestSupport { @Test public void testMvelTemplate() throws Exception { - Exchange exchange = template.request("direct:a", new Processor() { + Exchange exchange = template.request("direct:b", new Processor() { @Override public void process(Exchange exchange) throws Exception { exchange.getIn().setBody(7); @@ -54,7 +54,7 @@ public class MvelComponentTest extends CamelTestSupport { @Test public void testMvelUri() throws Exception { - Exchange exchange = template.request("direct:a", new Processor() { + Exchange exchange = template.request("direct:b", new Processor() { @Override public void process(Exchange exchange) throws Exception { exchange.getIn().setBody(7); @@ -72,6 +72,9 @@ public class MvelComponentTest extends CamelTestSupport { // START SNIPPET: example from("direct:a"). to("mvel:template.mvel"); + + from("direct:b"). + to("mvel:template.mvel?allowTemplateFromHeader=true"); // END SNIPPET: example } }; diff --git a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MvelComponentBuilderFactory.java b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MvelComponentBuilderFactory.java index 6809fea..aaab22e 100644 --- a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MvelComponentBuilderFactory.java +++ b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MvelComponentBuilderFactory.java @@ -47,6 +47,23 @@ public interface MvelComponentBuilderFactory { */ interface MvelComponentBuilder extends ComponentBuilder<MvelComponent> { /** + * Whether to allow to use resource template from header or not (default + * false). Enabling this allows to specify dynamic templates via message + * header. However this can be seen as a potential security + * vulnerability if the header is coming from a malicious user, so use + * this with care. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default MvelComponentBuilder allowTemplateFromHeader( + boolean allowTemplateFromHeader) { + doSetProperty("allowTemplateFromHeader", allowTemplateFromHeader); + return this; + } + /** * Whether the producer should be started lazy (on the first message). * By starting lazy you can use this to allow CamelContext and routes to * startup in situations where a producer may otherwise fail during @@ -97,6 +114,7 @@ public interface MvelComponentBuilderFactory { String name, Object value) { switch (name) { + case "allowTemplateFromHeader": ((MvelComponent) component).setAllowTemplateFromHeader((boolean) value); return true; case "lazyStartProducer": ((MvelComponent) component).setLazyStartProducer((boolean) value); return true; case "basicPropertyBinding": ((MvelComponent) component).setBasicPropertyBinding((boolean) value); return true; default: return false; diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MvelEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MvelEndpointBuilderFactory.java index bea8f96..6440e23 100644 --- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MvelEndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MvelEndpointBuilderFactory.java @@ -38,6 +38,40 @@ public interface MvelEndpointBuilderFactory { return (AdvancedMvelEndpointBuilder) this; } /** + * Whether to allow to use resource template from header or not (default + * false). Enabling this allows to specify dynamic templates via message + * header. However this can be seen as a potential security + * vulnerability if the header is coming from a malicious user, so use + * this with care. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default MvelEndpointBuilder allowTemplateFromHeader( + boolean allowTemplateFromHeader) { + doSetProperty("allowTemplateFromHeader", allowTemplateFromHeader); + return this; + } + /** + * Whether to allow to use resource template from header or not (default + * false). Enabling this allows to specify dynamic templates via message + * header. However this can be seen as a potential security + * vulnerability if the header is coming from a malicious user, so use + * this with care. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default MvelEndpointBuilder allowTemplateFromHeader( + String allowTemplateFromHeader) { + doSetProperty("allowTemplateFromHeader", allowTemplateFromHeader); + return this; + } + /** * Sets whether to use resource content cache or not. * * The option is a: <code>boolean</code> type.
