This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 5c3e362 CAMEL-16606 Allow specifying security requirement(s)
applicable to entire API (#5557)
5c3e362 is described below
commit 5c3e362f021f9085ed272705042758025289b515
Author: electrosaur <[email protected]>
AuthorDate: Thu May 13 21:10:38 2021 -0700
CAMEL-16606 Allow specifying security requirement(s) applicable to entire
API (#5557)
Calls to RestDefinition.security(String key [, String scopes]) without a
verb adds the security scheme specified by key
as a security requirement for all rest calls.
---
.../org/apache/camel/catalog/models.properties | 1 +
.../org/apache/camel/catalog/models/rest.json | 1 +
.../camel/catalog/models/securityRequirements.json | 16 +++
.../apache/camel/catalog/schemas/camel-spring.xsd | 15 +++
.../apache/camel/openapi/RestOpenApiReader.java | 21 ++++
...estOpenApiModelApiSecurityRequirementsTest.java | 123 +++++++++++++++++++++
.../services/org/apache/camel/model.properties | 1 +
.../org/apache/camel/model/rest/jaxb.index | 1 +
.../org/apache/camel/model/rest/rest.json | 1 +
.../camel/model/rest/securityRequirements.json | 16 +++
.../apache/camel/model/rest/RestDefinition.java | 30 ++++-
.../model/rest/RestSecuritiesRequirement.java | 90 +++++++++++++++
.../java/org/apache/camel/xml/in/ModelParser.java | 11 ++
.../dsl/yaml/deserializers/ModelDeserializers.java | 45 ++++++++
.../deserializers/ModelDeserializersResolver.java | 2 +
.../src/generated/resources/camel-yaml-dsl.json | 11 ++
16 files changed, 379 insertions(+), 6 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index 66ef3c0..353c9ff 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -158,6 +158,7 @@ secureRandomParameters
secureXML
security
securityDefinitions
+securityRequirements
serviceCall
serviceCallConfiguration
serviceChooserConfiguration
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/rest.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/rest.json
index 159564d..f4f5cc6 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/rest.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/rest.json
@@ -21,6 +21,7 @@
"enableCORS": { "kind": "attribute", "displayName": "Enable CORS",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description":
"Whether to enable CORS headers in the HTTP response. This option will override
what may be configured on a parent level The default value is false." },
"apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Whether to include or
exclude the VerbDefinition in API documentation. This option will override what
may be configured on a parent level The default value is true." },
"securityDefinitions": { "kind": "element", "displayName": "Security
Definitions", "required": false, "type": "object", "javaType":
"org.apache.camel.model.rest.RestSecuritiesDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the security
definitions such as Basic, OAuth2 etc." },
+ "securityRequirements": { "kind": "element", "displayName": "Security
Requirements", "required": false, "type": "object", "javaType":
"org.apache.camel.model.rest.RestSecuritiesRequirement", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the security
requirement(s) for all endpoints." },
"id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
"description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/securityRequirements.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/securityRequirements.json
new file mode 100644
index 0000000..9794558
--- /dev/null
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/securityRequirements.json
@@ -0,0 +1,16 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "securityRequirements",
+ "title": "Security Requirements",
+ "description": "To configure global rest security requirements.",
+ "deprecated": false,
+ "label": "rest,security",
+ "javaType": "org.apache.camel.model.rest.RestSecuritiesRequirement",
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "securityRequirements": { "kind": "element", "displayName": "Security
Requirements", "required": true, "type": "array", "javaType":
"java.util.List<org.apache.camel.model.rest.SecurityDefinition>", "oneOf": [
"securityRequirement" ], "deprecated": false, "autowired": false, "secret":
false }
+ }
+}
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 3c71d8e..3beb64c 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
@@ -1380,6 +1380,14 @@ To configure rest security definitions.
</xs:annotation>
</xs:element>
+ <xs:element name="securityRequirements" type="tns:restSecuritiesRequirement">
+ <xs:annotation>
+ <xs:documentation xml:lang="en"><![CDATA[
+To configure global rest security requirements.
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+
<xs:element name="serviceCall" type="tns:serviceCallDefinition">
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[
@@ -14042,6 +14050,7 @@ to refer to an existing data format instance.
<xs:extension base="tns:optionalIdentifiedDefinition">
<xs:sequence>
<xs:element minOccurs="0" ref="tns:securityDefinitions"/>
+ <xs:element minOccurs="0" ref="tns:securityRequirements"/>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element ref="tns:verb"/>
<xs:element ref="tns:delete"/>
@@ -14239,6 +14248,12 @@ password, application or accessCode.
</xs:complexContent>
</xs:complexType>
+ <xs:complexType name="restSecuritiesRequirement">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0"
name="securityRequirement" type="tns:securityDefinition"/>
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="restsDefinition">
<xs:complexContent>
<xs:extension base="tns:optionalIdentifiedDefinition">
diff --git
a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
index 004d80d..11ed7be 100644
---
a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
+++
b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
@@ -20,6 +20,8 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -48,6 +50,7 @@ import io.apicurio.datamodels.openapi.models.OasOperation;
import io.apicurio.datamodels.openapi.models.OasParameter;
import io.apicurio.datamodels.openapi.models.OasPathItem;
import io.apicurio.datamodels.openapi.models.OasSchema;
+import io.apicurio.datamodels.openapi.models.OasSecurityRequirement;
import io.apicurio.datamodels.openapi.v2.models.Oas20Document;
import io.apicurio.datamodels.openapi.v2.models.Oas20Header;
import io.apicurio.datamodels.openapi.v2.models.Oas20Items;
@@ -76,6 +79,7 @@ import
org.apache.camel.model.rest.RestOperationResponseMsgDefinition;
import org.apache.camel.model.rest.RestParamType;
import org.apache.camel.model.rest.RestPropertyDefinition;
import org.apache.camel.model.rest.RestSecuritiesDefinition;
+import org.apache.camel.model.rest.RestSecuritiesRequirement;
import org.apache.camel.model.rest.RestSecurityApiKey;
import org.apache.camel.model.rest.RestSecurityBasicAuth;
import org.apache.camel.model.rest.RestSecurityDefinition;
@@ -249,6 +253,23 @@ public class RestOpenApiReader {
}
doParseVerbs(camelContext, openApi, rest, camelContextId, verbs,
pathAsTag);
+
+ // setup root security node if necessary
+ RestSecuritiesRequirement securitiesRequirement =
rest.getSecurityRequirements();
+ if (securitiesRequirement != null) {
+ Collection<SecurityDefinition> securityRequirements =
securitiesRequirement.securityRequirements();
+ securityRequirements.forEach(requirement -> {
+ OasSecurityRequirement oasRequirement =
openApi.createSecurityRequirement();
+ List<String> scopes;
+ if (requirement.getScopes() == null ||
requirement.getScopes().trim().isEmpty()) {
+ scopes = Collections.emptyList();
+ } else {
+ scopes =
Arrays.asList(requirement.getScopes().trim().split("\\s*,\\s*"));
+ }
+
oasRequirement.addSecurityRequirementItem(requirement.getKey(), scopes);
+ openApi.addSecurityRequirement(oasRequirement);
+ });
+ }
}
private void parseOas30(Oas30Document openApi, RestDefinition rest, String
pathAsTag) {
diff --git
a/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiModelApiSecurityRequirementsTest.java
b/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiModelApiSecurityRequirementsTest.java
new file mode 100644
index 0000000..cc1b5bc
--- /dev/null
+++
b/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiModelApiSecurityRequirementsTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.openapi;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import io.apicurio.datamodels.Library;
+import io.apicurio.datamodels.openapi.models.OasDocument;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.engine.DefaultClassResolver;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class RestOpenApiModelApiSecurityRequirementsTest extends
CamelTestSupport {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ rest()
+ .securityDefinitions()
+ .oauth2("petstore_auth")
+
.authorizationUrl("https://petstore.swagger.io/oauth/dialog")
+ .end()
+ .apiKey("api_key")
+ .withHeader("myHeader").end()
+ .end()
+ .security("petstore_auth", "read, write")
+ .security("api_key");
+ }
+ };
+ }
+
+ @Test
+ public void testReaderRead() throws Exception {
+ BeanConfig config = new BeanConfig();
+ config.setHost("localhost:8080");
+ config.setSchemes(new String[] { "http" });
+ config.setBasePath("/api");
+ config.setTitle("Camel User store");
+ config.setLicense("Apache 2.0");
+
config.setLicenseUrl("https://www.apache.org/licenses/LICENSE-2.0.html");
+ config.setVersion("2.0");
+ RestOpenApiReader reader = new RestOpenApiReader();
+
+ OasDocument openApi = reader.read(context,
context.getRestDefinitions(), null, config, context.getName(),
+ new DefaultClassResolver());
+ assertNotNull(openApi);
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ Object dump = Library.writeNode(openApi);
+ String json = mapper.writeValueAsString(dump);
+
+ log.info(json);
+
+ assertTrue(json.contains("\"securityDefinitions\" : {"));
+ assertTrue(json.contains("\"type\" : \"oauth2\""));
+ assertTrue(json.contains("\"authorizationUrl\" :
\"https://petstore.swagger.io/oauth/dialog\""));
+ assertTrue(json.contains("\"flow\" : \"implicit\""));
+ assertTrue(json.contains("\"type\" : \"apiKey\","));
+ assertTrue(json.contains("\"security\" : [ {"));
+ assertTrue(json.contains("\"petstore_auth\" : [ \"read\", \"write\"
]"));
+ assertTrue(json.contains("\"api_key\" : [ ]"));
+ }
+
+ @Test
+ public void testReaderReadV3() throws Exception {
+ BeanConfig config = new BeanConfig();
+ config.setHost("localhost:8080");
+ config.setSchemes(new String[] { "http" });
+ config.setBasePath("/api");
+ config.setTitle("Camel User store");
+ config.setLicense("Apache 2.0");
+
config.setLicenseUrl("https://www.apache.org/licenses/LICENSE-2.0.html");
+ RestOpenApiReader reader = new RestOpenApiReader();
+
+ OasDocument openApi = reader.read(context,
context.getRestDefinitions(), null, config, context.getName(),
+ new DefaultClassResolver());
+ assertNotNull(openApi);
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ Object dump = Library.writeNode(openApi);
+ String json = mapper.writeValueAsString(dump);
+
+ log.info(json);
+
+ assertTrue(json.contains("securitySchemes"));
+ assertTrue(json.contains("\"type\" : \"oauth2\""));
+ assertTrue(json.contains("\"authorizationUrl\" :
\"https://petstore.swagger.io/oauth/dialog\""));
+ assertTrue(json.contains("\"flows\" : {"));
+ assertTrue(json.contains("\"implicit\""));
+ assertTrue(json.contains("\"security\" : [ {"));
+ assertTrue(json.contains("\"petstore_auth\" : [ \"read\", \"write\"
]"));
+ assertTrue(json.contains("\"api_key\" : [ ]"));
+ }
+}
diff --git
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index b94ed3b..19029a3 100644
---
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -147,6 +147,7 @@ script
secureXML
security
securityDefinitions
+securityRequirements
serviceCall
serviceCallConfiguration
serviceChooserConfiguration
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/jaxb.index
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/jaxb.index
index 695418d..402f653 100644
---
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/jaxb.index
+++
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/jaxb.index
@@ -17,6 +17,7 @@ RestOperationResponseMsgDefinition
RestParamType
RestPropertyDefinition
RestSecuritiesDefinition
+RestSecuritiesRequirement
RestSecurityApiKey
RestSecurityBasicAuth
RestSecurityOAuth2
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/rest.json
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/rest.json
index 159564d..f4f5cc6 100644
---
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/rest.json
+++
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/rest.json
@@ -21,6 +21,7 @@
"enableCORS": { "kind": "attribute", "displayName": "Enable CORS",
"required": false, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, "secret": false, "description":
"Whether to enable CORS headers in the HTTP response. This option will override
what may be configured on a parent level The default value is false." },
"apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Whether to include or
exclude the VerbDefinition in API documentation. This option will override what
may be configured on a parent level The default value is true." },
"securityDefinitions": { "kind": "element", "displayName": "Security
Definitions", "required": false, "type": "object", "javaType":
"org.apache.camel.model.rest.RestSecuritiesDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the security
definitions such as Basic, OAuth2 etc." },
+ "securityRequirements": { "kind": "element", "displayName": "Security
Requirements", "required": false, "type": "object", "javaType":
"org.apache.camel.model.rest.RestSecuritiesRequirement", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the security
requirement(s) for all endpoints." },
"id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
"description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
}
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/securityRequirements.json
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/securityRequirements.json
new file mode 100644
index 0000000..9794558
--- /dev/null
+++
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/securityRequirements.json
@@ -0,0 +1,16 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "securityRequirements",
+ "title": "Security Requirements",
+ "description": "To configure global rest security requirements.",
+ "deprecated": false,
+ "label": "rest,security",
+ "javaType": "org.apache.camel.model.rest.RestSecuritiesRequirement",
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "securityRequirements": { "kind": "element", "displayName": "Security
Requirements", "required": true, "type": "array", "javaType":
"java.util.List<org.apache.camel.model.rest.SecurityDefinition>", "oneOf": [
"securityRequirement" ], "deprecated": false, "autowired": false, "secret":
false }
+ }
+}
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index f5eff4e..abbd4b4 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -87,6 +87,9 @@ public class RestDefinition extends
OptionalIdentifiedDefinition<RestDefinition>
@XmlElement(name = "securityDefinitions") // use the name swagger uses
private RestSecuritiesDefinition securityDefinitions;
+ @XmlElement(name = "securityRequirements") // use the name swagger/OpenAPI
uses
+ private RestSecuritiesRequirement securityRequirements;
+
@XmlElementRef
private List<VerbDefinition> verbs = new ArrayList<>();
@@ -174,6 +177,17 @@ public class RestDefinition extends
OptionalIdentifiedDefinition<RestDefinition>
this.securityDefinitions = securityDefinitions;
}
+ public RestSecuritiesRequirement getSecurityRequirements() {
+ return securityRequirements;
+ }
+
+ /**
+ * Sets the security requirement(s) for all endpoints.
+ */
+ public void setSecurityRequirements(RestSecuritiesRequirement
securityRequirements) {
+ this.securityRequirements = securityRequirements;
+ }
+
/**
* The HTTP verbs this REST service accepts and uses
*/
@@ -562,14 +576,18 @@ public class RestDefinition extends
OptionalIdentifiedDefinition<RestDefinition>
public RestDefinition security(String key, String scopes) {
// add to last verb
if (getVerbs().isEmpty()) {
- throw new IllegalArgumentException("Must add verb first, such as
get/post/delete");
+ if (securityRequirements == null) {
+ securityRequirements = new RestSecuritiesRequirement();
+ }
+ securityRequirements.securityRequirement(key, scopes);
+ } else {
+ VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
+ SecurityDefinition sd = new SecurityDefinition();
+ sd.setKey(key);
+ sd.setScopes(scopes);
+ verb.getSecurity().add(sd);
}
- VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
- SecurityDefinition sd = new SecurityDefinition();
- sd.setKey(key);
- sd.setScopes(scopes);
- verb.getSecurity().add(sd);
return this;
}
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestSecuritiesRequirement.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestSecuritiesRequirement.java
new file mode 100644
index 0000000..4956823
--- /dev/null
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestSecuritiesRequirement.java
@@ -0,0 +1,90 @@
+/*
+ * 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.model.rest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * To configure global rest security requirements.
+ */
+@Metadata(label = "rest,security", title = "Security Requirements")
+@XmlRootElement(name = "securityRequirements")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RestSecuritiesRequirement {
+ @XmlTransient
+ RestDefinition rest;
+
+ @XmlTransient
+ Map<String, SecurityDefinition> itemsMap = new HashMap<>();
+
+ @XmlElements({ @XmlElement(name = "securityRequirement", type =
SecurityDefinition.class) })
+ List<SecurityDefinition> securityRequirements = new ArrayList<>();
+
+ public RestSecuritiesRequirement() {
+ }
+
+ public RestSecuritiesRequirement(RestDefinition rest) {
+ this.rest = rest;
+ }
+
+ public RestDefinition securityRequirement(String key) {
+ return securityRequirement(key, null);
+ }
+
+ public RestDefinition securityRequirement(String key, String scopes) {
+ SecurityDefinition requirement = itemsMap.get(key);
+ if (requirement == null) {
+ requirement = new SecurityDefinition();
+ }
+
+ requirement.setKey(key);
+ requirement.setScopes(scopes);
+ itemsMap.put(key, requirement);
+ securityRequirements = new ArrayList<>(itemsMap.values());
+
+ return rest;
+ }
+
+ public Collection<SecurityDefinition> securityRequirements() {
+ return new ArrayList<>(securityRequirements);
+ }
+
+ public List<SecurityDefinition> getSecurityRequirements() {
+ return securityRequirements;
+ }
+
+ public void setSecurityRequirements(Collection<SecurityDefinition>
securityRequirements) {
+ itemsMap = securityRequirements.stream()
+ .collect(Collectors.toMap(SecurityDefinition::getKey,
Function.identity(), (u, v) -> u));
+ this.securityRequirements = new ArrayList<>(itemsMap.values());
+ }
+}
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 b8e7249..7acb0c7 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
@@ -998,6 +998,7 @@ public class ModelParser extends BaseParser {
case "post": doAdd(doParsePostVerbDefinition(),
def.getVerbs(), def::setVerbs); break;
case "put": doAdd(doParsePutVerbDefinition(), def.getVerbs(),
def::setVerbs); break;
case "securityDefinitions":
def.setSecurityDefinitions(doParseRestSecuritiesDefinition()); break;
+ case "securityRequirements":
def.setSecurityRequirements(doParseRestSecuritiesRequirement()); break;
default: return
optionalIdentifiedDefinitionElementHandler().accept(def, key);
}
return true;
@@ -2760,6 +2761,16 @@ public class ModelParser extends BaseParser {
return true;
}, noValueHandler());
}
+ protected RestSecuritiesRequirement doParseRestSecuritiesRequirement()
throws IOException, XmlPullParserException {
+ return doParse(new RestSecuritiesRequirement(),
+ noAttributeHandler(), (def, key) -> {
+ if ("securityRequirement".equals(key)) {
+ doAdd(doParseSecurityDefinition(),
def.getSecurityRequirements(), def::setSecurityRequirements);
+ return true;
+ }
+ return false;
+ }, noValueHandler());
+ }
protected RestOperationResponseHeaderDefinition
doParseRestOperationResponseHeaderDefinition() throws IOException,
XmlPullParserException {
return doParse(new RestOperationResponseHeaderDefinition(), (def, key,
val) -> {
switch (key) {
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 8adf1ca..4c30fdf 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
@@ -212,6 +212,7 @@ import
org.apache.camel.model.rest.RestOperationResponseHeaderDefinition;
import org.apache.camel.model.rest.RestOperationResponseMsgDefinition;
import org.apache.camel.model.rest.RestPropertyDefinition;
import org.apache.camel.model.rest.RestSecuritiesDefinition;
+import org.apache.camel.model.rest.RestSecuritiesRequirement;
import org.apache.camel.model.rest.RestSecurityApiKey;
import org.apache.camel.model.rest.RestSecurityBasicAuth;
import org.apache.camel.model.rest.RestSecurityOAuth2;
@@ -10835,6 +10836,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "path", type = "string"),
@YamlProperty(name = "produces", type = "string"),
@YamlProperty(name = "security-definitions", type =
"object:org.apache.camel.model.rest.RestSecuritiesDefinition"),
+ @YamlProperty(name = "security-requirements", type =
"object:org.apache.camel.model.rest.RestSecuritiesRequirement"),
@YamlProperty(name = "skip-binding-on-error-code", type =
"string"),
@YamlProperty(name = "tag", type = "string"),
@YamlProperty(name = "verb", type =
"array:org.apache.camel.model.rest.VerbDefinition")
@@ -10894,6 +10896,11 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
target.setSecurityDefinitions(val);
break;
}
+ case "security-requirements": {
+ org.apache.camel.model.rest.RestSecuritiesRequirement val
= asType(node, org.apache.camel.model.rest.RestSecuritiesRequirement.class);
+ target.setSecurityRequirements(val);
+ break;
+ }
case "skip-binding-on-error-code": {
String val = asText(node);
target.setSkipBindingOnErrorCode(val);
@@ -11254,6 +11261,44 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
}
@YamlType(
+ types =
org.apache.camel.model.rest.RestSecuritiesRequirement.class,
+ order =
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+ nodes = "security-requirements",
+ properties = @YamlProperty(name = "security-requirement", type =
"object:org.apache.camel.model.rest.SecurityDefinition")
+ )
+ public static class RestSecuritiesRequirementDeserializer extends
YamlDeserializerBase<RestSecuritiesRequirement> {
+ public RestSecuritiesRequirementDeserializer() {
+ super(RestSecuritiesRequirement.class);
+ }
+
+ @Override
+ protected RestSecuritiesRequirement newInstance() {
+ return new RestSecuritiesRequirement();
+ }
+
+ @Override
+ protected boolean setProperty(RestSecuritiesRequirement target, String
propertyKey,
+ String propertyName, Node node) {
+ switch(propertyKey) {
+ case "security-requirement": {
+ org.apache.camel.model.rest.SecurityDefinition val =
asType(node, org.apache.camel.model.rest.SecurityDefinition.class);
+
java.util.List<org.apache.camel.model.rest.SecurityDefinition> existing =
target.getSecurityRequirements();
+ if (existing == null) {
+ existing = new java.util.ArrayList<>();
+ }
+ existing.add(val);
+ target.setSecurityRequirements(existing);
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ @YamlType(
types = org.apache.camel.model.rest.RestSecurityApiKey.class,
order =
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
nodes = "api-key",
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index b27616c..737c084 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -272,6 +272,8 @@ public final class ModelDeserializersResolver implements
YamlDeserializerResolve
case "org.apache.camel.model.rest.RestPropertyDefinition": return
new ModelDeserializers.RestPropertyDefinitionDeserializer();
case "security-definitions": return new
ModelDeserializers.RestSecuritiesDefinitionDeserializer();
case "org.apache.camel.model.rest.RestSecuritiesDefinition":
return new ModelDeserializers.RestSecuritiesDefinitionDeserializer();
+ case "security-requirements": return new
ModelDeserializers.RestSecuritiesRequirementDeserializer();
+ case "org.apache.camel.model.rest.RestSecuritiesRequirement":
return new ModelDeserializers.RestSecuritiesRequirementDeserializer();
case "api-key": return new
ModelDeserializers.RestSecurityApiKeyDeserializer();
case "org.apache.camel.model.rest.RestSecurityApiKey": return new
ModelDeserializers.RestSecurityApiKeyDeserializer();
case "basic-auth": return new
ModelDeserializers.RestSecurityBasicAuthDeserializer();
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
index 6bb22ec..58863262a 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
@@ -6386,6 +6386,9 @@
"security-definitions" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.rest.RestSecuritiesDefinition"
},
+ "security-requirements" : {
+ "$ref" :
"#/items/definitions/org.apache.camel.model.rest.RestSecuritiesRequirement"
+ },
"skip-binding-on-error-code" : {
"type" : "string"
},
@@ -6534,6 +6537,14 @@
}
}
},
+ "org.apache.camel.model.rest.RestSecuritiesRequirement" : {
+ "type" : "object",
+ "properties" : {
+ "security-requirement" : {
+ "$ref" :
"#/items/definitions/org.apache.camel.model.rest.SecurityDefinition"
+ }
+ }
+ },
"org.apache.camel.model.rest.RestSecurityApiKey" : {
"type" : "object",
"properties" : {