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-quarkus.git
The following commit(s) were added to refs/heads/master by this push: new bcc062e Fix #1212 - Add the allowTemplateFromHeader option in the qute component (#1241) bcc062e is described below commit bcc062efa35482c1bc828aa003fbe1eafcccf0ac Author: Amos Feng <zf...@redhat.com> AuthorDate: Tue May 19 12:53:46 2020 +0800 Fix #1212 - Add the allowTemplateFromHeader option in the qute component (#1241) --- .../component/qute/QuteComponentConfigurer.java | 5 +++ .../component/qute/QuteEndpointConfigurer.java | 5 +++ .../org/apache/camel/component/qute/qute.json | 2 + .../apache/camel/component/qute/QuteComponent.java | 20 ++++++++- .../apache/camel/component/qute/QuteEndpoint.java | 49 ++++++++++++++++------ .../qute/QuteSetTemplateViaHeaderTest.java | 2 +- .../component/qute/QuteTemplateInHeaderTest.java | 2 +- 7 files changed, 70 insertions(+), 15 deletions(-) diff --git a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java index 0e903b1..8ecaf3e 100644 --- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java +++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteComponentConfigurer.java @@ -19,6 +19,8 @@ public class QuteComponentConfigurer extends PropertyConfigurerSupport implement public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { QuteComponent target = (QuteComponent) 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": @@ -32,6 +34,7 @@ public class QuteComponentConfigurer 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); answer.put("quteEngine", io.quarkus.qute.Engine.class); @@ -42,6 +45,8 @@ public class QuteComponentConfigurer extends PropertyConfigurerSupport implement public Object getOptionValue(Object obj, String name, boolean ignoreCase) { QuteComponent target = (QuteComponent) 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/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java index 059e63e..f4ca33c 100644 --- a/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java +++ b/extensions/qute/component/src/generated/java/org/apache/camel/component/qute/QuteEndpointConfigurer.java @@ -19,6 +19,8 @@ public class QuteEndpointConfigurer extends PropertyConfigurerSupport implements public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { QuteEndpoint target = (QuteEndpoint) 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 QuteEndpointConfigurer 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 QuteEndpointConfigurer extends PropertyConfigurerSupport implements public Object getOptionValue(Object obj, String name, boolean ignoreCase) { QuteEndpoint target = (QuteEndpoint) 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/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json b/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json index 481d51d..6642da3 100644 --- a/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json +++ b/extensions/qute/component/src/generated/resources/org/apache/camel/component/qute/qute.json @@ -21,12 +21,14 @@ "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" }, "quteEngine": { "kind": "property", "displayName": "Qute Engine", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "io.quarkus.qute.Engine", "deprecated": false, "secret": false, "description": "To use the Engine otherwise a new engine is created" } }, "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/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteComponent.java b/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteComponent.java index c778c44..99c5ee6 100644 --- a/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteComponent.java +++ b/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteComponent.java @@ -28,6 +28,8 @@ import org.apache.camel.support.ResourceHelper; @Component("qute") public class QuteComponent extends DefaultComponent { + @Metadata(defaultValue = "false") + private boolean allowTemplateFromHeader; @Metadata(label = "advanced") private Engine quteEngine; @@ -45,15 +47,31 @@ public class QuteComponent extends DefaultComponent { this.quteEngine = quteEngine; } + 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; + } + @Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { boolean cache = getAndRemoveParameter(parameters, "contentCache", Boolean.class, Boolean.TRUE); QuteEndpoint answer = new QuteEndpoint(uri, this, remaining); - setProperties(answer, parameters); answer.setContentCache(cache); + answer.setAllowTemplateFromHeader(allowTemplateFromHeader); answer.setQuteEngine(quteEngine); + setProperties(answer, parameters); + // if its a http resource then append any remaining parameters and update the resource uri if (ResourceHelper.isHttpUri(remaining)) { remaining = ResourceHelper.appendParameters(remaining, parameters); diff --git a/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteEndpoint.java b/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteEndpoint.java index c52fa24..9da90a3 100644 --- a/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteEndpoint.java +++ b/extensions/qute/component/src/main/java/org/apache/camel/component/qute/QuteEndpoint.java @@ -44,6 +44,8 @@ import org.apache.camel.util.ObjectHelper; public class QuteEndpoint extends ResourceEndpoint { private Engine quteEngine; + @UriParam(defaultValue = "false") + private boolean allowTemplateFromHeader; @UriParam private String encoding; @@ -74,6 +76,20 @@ public class QuteEndpoint extends ResourceEndpoint { return quteEngine; } + 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; + } + private Optional<TemplateLocation> locate(String path) { return Optional.of(new TemplateLocation() { private URL locatePath(String path) { @@ -133,23 +149,32 @@ public class QuteEndpoint extends ResourceEndpoint { String path = getResourceUri(); ObjectHelper.notNull(path, "resourceUri"); - String newResourceUri = exchange.getIn().getHeader(QuteConstants.QUTE_RESOURCE_URI, String.class); - if (newResourceUri != null) { - exchange.getIn().removeHeader(QuteConstants.QUTE_RESOURCE_URI); + if (allowTemplateFromHeader) { + String newResourceUri = exchange.getIn().getHeader(QuteConstants.QUTE_RESOURCE_URI, String.class); + if (newResourceUri != null) { + exchange.getIn().removeHeader(QuteConstants.QUTE_RESOURCE_URI); - log.debug("{} set to {} creating new endpoint to handle exchange", QuteConstants.QUTE_RESOURCE_URI, newResourceUri); - QuteEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri); - newEndpoint.onExchange(exchange); - return; + log.debug("{} set to {} creating new endpoint to handle exchange", QuteConstants.QUTE_RESOURCE_URI, + newResourceUri); + QuteEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri); + newEndpoint.onExchange(exchange); + return; + } } - String content = exchange.getIn().getHeader(QuteConstants.QUTE_TEMPLATE, String.class); - if (content != null) { - // remove the header to avoid it being propagated in the routing - exchange.getIn().removeHeader(QuteConstants.QUTE_TEMPLATE); + String content = null; + if (allowTemplateFromHeader) { + content = exchange.getIn().getHeader(QuteConstants.QUTE_TEMPLATE, String.class); + if (content != null) { + // remove the header to avoid it being propagated in the routing + exchange.getIn().removeHeader(QuteConstants.QUTE_TEMPLATE); + } } - TemplateInstance instance = exchange.getIn().getHeader(QuteConstants.QUTE_TEMPLATE_INSTANCE, TemplateInstance.class); + TemplateInstance instance = null; + if (allowTemplateFromHeader) { + instance = exchange.getIn().getHeader(QuteConstants.QUTE_TEMPLATE_INSTANCE, TemplateInstance.class); + } if (instance != null) { // use template instance from header if (log.isDebugEnabled()) { diff --git a/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteSetTemplateViaHeaderTest.java b/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteSetTemplateViaHeaderTest.java index 2ad00af..1c17b8c 100644 --- a/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteSetTemplateViaHeaderTest.java +++ b/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteSetTemplateViaHeaderTest.java @@ -59,7 +59,7 @@ public class QuteSetTemplateViaHeaderTest extends CamelTestSupport { protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { - from("direct:a").to("qute:dummy").to("mock:result"); + from("direct:a").to("qute:dummy?allowTemplateFromHeader=true").to("mock:result"); } }; } diff --git a/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteTemplateInHeaderTest.java b/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteTemplateInHeaderTest.java index e4d76bb..7671c12 100644 --- a/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteTemplateInHeaderTest.java +++ b/extensions/qute/component/src/test/java/org/apache/camel/component/qute/QuteTemplateInHeaderTest.java @@ -76,7 +76,7 @@ public class QuteTemplateInHeaderTest extends CamelTestSupport { protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { - from("direct:a").to("qute://dummy"); + from("direct:a").to("qute://dummy?allowTemplateFromHeader=true"); } }; }