camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [camel] 03/04: CAMEL-9751: Allow to configure swagger security requirements in generated swagger api docs in rest-dsl.
Date Mon, 18 Jun 2018 08:31:21 GMT
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 a459ecd029f9e4f1481a3c6940cdde3a781f4e06
Author: Claus Ibsen <claus.ibsen@gmail.com>
AuthorDate: Sun Jun 17 10:33:16 2018 +0200

    CAMEL-9751: Allow to configure swagger security requirements in generated swagger api
docs in rest-dsl.
---
 .../apache/camel/model/rest/RestDefinition.java    | 24 ++++++++
 .../camel/model/rest/SecurityDefinition.java       | 58 ++++++++++++++++++
 .../apache/camel/model/rest/VerbDefinition.java    | 14 +++++
 .../org/apache/camel/model/rest/jaxb.index         |  1 +
 .../apache/camel/component/rest/RestRefTest.xml    |  1 +
 .../src/main/docs/swagger-java.adoc                | 50 +++++++++++++---
 .../apache/camel/swagger/RestSwaggerReader.java    | 70 ++++++++++++++--------
 .../RestSwaggerReaderModelApiSecurityTest.java     |  7 +++
 8 files changed, 191 insertions(+), 34 deletions(-)

diff --git a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index 5583def..ff8866d 100644
--- a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -573,6 +573,30 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
     }
 
     /**
+     * Sets the security setting for this verb.
+     */
+    public RestDefinition security(String key) {
+        return security(key, null);
+    }
+
+    /**
+     * Sets the security setting for this verb.
+     */
+    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");
+        }
+
+        VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
+        SecurityDefinition sd = new SecurityDefinition();
+        sd.setKey(key);
+        sd.setScopes(scopes);
+        verb.getSecurity().add(sd);
+        return this;
+    }
+
+    /**
      * Routes directly to the given static endpoint.
      * <p/>
      * If you need additional routing capabilities, then use {@link #route()} instead.
diff --git a/camel-core/src/main/java/org/apache/camel/model/rest/SecurityDefinition.java
b/camel-core/src/main/java/org/apache/camel/model/rest/SecurityDefinition.java
new file mode 100644
index 0000000..52ea20d
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/rest/SecurityDefinition.java
@@ -0,0 +1,58 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "rest,security", title = "Security")
+@XmlRootElement(name = "security")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class SecurityDefinition {
+
+    @XmlAttribute(required = true) @Metadata(required = "true")
+    private String key;
+
+    @XmlAttribute
+    private String scopes;
+
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * Key used to refer to this security definition
+     */
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getScopes() {
+        return scopes;
+    }
+
+    /**
+     * The scopes to allow (separate multiple scopes by comma)
+     */
+    public void setScopes(String scopes) {
+        this.scopes = scopes;
+    }
+}
diff --git a/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java b/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
index fbc2055..27ad9fd 100644
--- a/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
@@ -52,6 +52,9 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition>
     @XmlElementRef
     private List<RestOperationResponseMsgDefinition> responseMsgs = new ArrayList<>();
 
+    @XmlElementRef
+    private List<SecurityDefinition> security = new ArrayList<>();
+
     @XmlAttribute
     private String uri;
 
@@ -138,6 +141,17 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition>
         this.responseMsgs = responseMsgs;
     }
 
+    public List<SecurityDefinition> getSecurity() {
+        return security;
+    }
+
+    /**
+     * Sets the swagger security settings for this verb.
+     */
+    public void setSecurity(List<SecurityDefinition> security) {
+        this.security = security;
+    }
+
     public String getMethod() {
         return method;
     }
diff --git a/camel-core/src/main/resources/org/apache/camel/model/rest/jaxb.index b/camel-core/src/main/resources/org/apache/camel/model/rest/jaxb.index
index e032df8..a9c8a6a 100644
--- a/camel-core/src/main/resources/org/apache/camel/model/rest/jaxb.index
+++ b/camel-core/src/main/resources/org/apache/camel/model/rest/jaxb.index
@@ -37,4 +37,5 @@ RestSecurityApiKey
 RestSecurityBasicAuth
 RestSecuritiesDefinition
 RestSecurityOAuth2
+SecurityDefinition
 VerbDefinition
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/component/rest/RestRefTest.xml
b/components/camel-spring/src/test/resources/org/apache/camel/component/rest/RestRefTest.xml
index c53d943..732c73f 100644
--- a/components/camel-spring/src/test/resources/org/apache/camel/component/rest/RestRefTest.xml
+++ b/components/camel-spring/src/test/resources/org/apache/camel/component/rest/RestRefTest.xml
@@ -31,6 +31,7 @@
     <rest path="/say/hello">
       <get>
         <to uri="direct:hello"/>
+        <security key="ausss" scopes="write:pets,read:pets"/>
       </get>
     </rest>
   </restContext>
diff --git a/components/camel-swagger-java/src/main/docs/swagger-java.adoc b/components/camel-swagger-java/src/main/docs/swagger-java.adoc
index 0983f5d..02dbe61 100644
--- a/components/camel-swagger-java/src/main/docs/swagger-java.adoc
+++ b/components/camel-swagger-java/src/main/docs/swagger-java.adoc
@@ -9,9 +9,6 @@ services and their APIs using http://swagger.io/[Swagger].
 Maven users will need to add the following dependency to
 their `pom.xml` for this component:
 
-From *Camel 2.16* onwards the swagger component is purely Java based,
-and its 
-
 [source,xml]
 ----
 <dependency>
@@ -25,9 +22,6 @@ and its 
 The camel-swagger-java module can be used from
 the REST components (without the need for servlet)
 
-For an example see the `camel-example-swagger-cdi` in the examples
-directory of the Apache Camel distribution.
-
 
 === Using Swagger in rest-dsl
 
@@ -82,8 +76,7 @@ with `api.xxx` is configured using `apiProperty` dsl.
 
 |cors |Boolean |Whether to enable CORS. Notice this only enables CORS for the api
 browser, and not the actual access to the REST services. Is default
-false. Instead of using this option is recommended to use the CorsFilte, see
-further below.
+false.
 
 |swagger.version |String |Swagger spec version. Is default 2.0.
 
@@ -138,6 +131,47 @@ wildcard. Its the same pattern matching as used by
 Intercept
 |===
 
+=== Adding Security Definitions in API doc
+
+*Available as of Camel 2.22.0*
+
+The Rest DSL now supports declaring Swagger `securityDefinitions` in the generated API document.
+For example as shown below:
+
+[source,java]
+----
+rest("/user").tag("dude").description("User rest service")
+    // setup security definitions
+    .securityDefinitions()
+        .oauth2("petstore_auth").authorizationUrl("http://petstore.swagger.io/oauth/dialog").end()
+        .apiKey("api_key").withHeader("myHeader").end()
+    .end()
+    .consumes("application/json").produces("application/json")
+----
+
+Here we have setup two security definitions
+
+- OAuth2 - with implicit authorization with the provided url
+- Api Key - using an api key that comes from HTTP header named _myHeader_
+
+Then you need to specify on the rest operations which security to use by referring to
+their key (petstore_auth or api_key).
+
+[source,java]
+----
+.get("/{id}/{date}").description("Find user by id and date").outType(User.class)
+    .security("api_key")
+
+...
+
+.put().description("Updates or create a user").type(User.class)
+    .security("petstore_auth", "write:pets,read:pets")
+----
+
+Here the get operation is using the Api Key security and the put operation
+is using OAuth security with permitted scopes of read and write pets.
+
+
 
 === ContextIdListing enabled
 
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
index c100ae8..128ea21 100644
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
@@ -21,6 +21,7 @@ import java.lang.invoke.MethodType;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
@@ -39,6 +40,7 @@ import io.swagger.models.Operation;
 import io.swagger.models.Path;
 import io.swagger.models.RefModel;
 import io.swagger.models.Response;
+import io.swagger.models.SecurityRequirement;
 import io.swagger.models.Swagger;
 import io.swagger.models.Tag;
 import io.swagger.models.auth.ApiKeyAuthDefinition;
@@ -74,6 +76,7 @@ import org.apache.camel.model.rest.RestSecurityApiKey;
 import org.apache.camel.model.rest.RestSecurityBasicAuth;
 import org.apache.camel.model.rest.RestSecurityDefinition;
 import org.apache.camel.model.rest.RestSecurityOAuth2;
+import org.apache.camel.model.rest.SecurityDefinition;
 import org.apache.camel.model.rest.VerbDefinition;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.util.FileUtil;
@@ -134,33 +137,35 @@ public class RestSwaggerReader {
 
         // setup security definitions
         RestSecuritiesDefinition sd = rest.getSecurityDefinitions();
-        for (RestSecurityDefinition def : sd.getSecurityDefinitions()) {
-            if (def instanceof RestSecurityBasicAuth) {
-                BasicAuthDefinition auth = new BasicAuthDefinition();
-                auth.setDescription(def.getDescription());
-                swagger.addSecurityDefinition(def.getKey(), auth);
-            } else if (def instanceof RestSecurityApiKey) {
-                RestSecurityApiKey rs = (RestSecurityApiKey) def;
-                ApiKeyAuthDefinition auth = new ApiKeyAuthDefinition();
-                auth.setDescription(rs.getDescription());
-                auth.setName(rs.getName());
-                if (rs.getInHeader() != null && rs.getInHeader()) {
-                    auth.setIn(In.HEADER);
-                } else {
-                    auth.setIn(In.QUERY);
-                }
-                swagger.addSecurityDefinition(def.getKey(), auth);
-            } else if (def instanceof RestSecurityOAuth2) {
-                RestSecurityOAuth2 rs = (RestSecurityOAuth2) def;
-                OAuth2Definition auth = new OAuth2Definition();
-                auth.setDescription(rs.getDescription());
-                auth.setFlow(rs.getFlow());
-                auth.setAuthorizationUrl(rs.getAuthorizationUrl());
-                auth.setTokenUrl(rs.getTokenUrl());
-                for (RestPropertyDefinition scope : rs.getScopes()) {
-                    auth.addScope(scope.getKey(), scope.getValue());
+        if (sd != null) {
+            for (RestSecurityDefinition def : sd.getSecurityDefinitions()) {
+                if (def instanceof RestSecurityBasicAuth) {
+                    BasicAuthDefinition auth = new BasicAuthDefinition();
+                    auth.setDescription(def.getDescription());
+                    swagger.addSecurityDefinition(def.getKey(), auth);
+                } else if (def instanceof RestSecurityApiKey) {
+                    RestSecurityApiKey rs = (RestSecurityApiKey) def;
+                    ApiKeyAuthDefinition auth = new ApiKeyAuthDefinition();
+                    auth.setDescription(rs.getDescription());
+                    auth.setName(rs.getName());
+                    if (rs.getInHeader() != null && rs.getInHeader()) {
+                        auth.setIn(In.HEADER);
+                    } else {
+                        auth.setIn(In.QUERY);
+                    }
+                    swagger.addSecurityDefinition(def.getKey(), auth);
+                } else if (def instanceof RestSecurityOAuth2) {
+                    RestSecurityOAuth2 rs = (RestSecurityOAuth2) def;
+                    OAuth2Definition auth = new OAuth2Definition();
+                    auth.setDescription(rs.getDescription());
+                    auth.setFlow(rs.getFlow());
+                    auth.setAuthorizationUrl(rs.getAuthorizationUrl());
+                    auth.setTokenUrl(rs.getTokenUrl());
+                    for (RestPropertyDefinition scope : rs.getScopes()) {
+                        auth.addScope(scope.getKey(), scope.getValue());
+                    }
+                    swagger.addSecurityDefinition(def.getKey(), auth);
                 }
-                swagger.addSecurityDefinition(def.getKey(), auth);
             }
         }
 
@@ -281,6 +286,19 @@ public class RestSwaggerReader {
                 op.summary(verb.getDescriptionText());
             }
 
+            // security
+            for (SecurityDefinition sd : verb.getSecurity()) {
+                List<String> scopes = new ArrayList<>();
+                if (sd.getScopes() != null) {
+                    Iterator<Object> it = ObjectHelper.createIterator(sd.getScopes());
+                    while (it.hasNext()) {
+                        String scope = it.next().toString();
+                        scopes.add(scope);
+                    }
+                }
+                op.addSecurity(sd.getKey(), scopes);
+            }
+
             for (RestOperationParamDefinition param : verb.getParams()) {
                 Parameter parameter = null;
                 if (param.getType().equals(RestParamType.body)) {
diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderModelApiSecurityTest.java
b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderModelApiSecurityTest.java
index dcebc21..c8708d2 100644
--- a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderModelApiSecurityTest.java
+++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderModelApiSecurityTest.java
@@ -52,11 +52,15 @@ public class RestSwaggerReaderModelApiSecurityTest extends CamelTestSupport
{
 
                     .get("/{id}/{date}").description("Find user by id and date").outType(User.class)
                         .responseMessage().message("The user returned").endResponseMessage()
+                        // setup security for this rest verb
+                        .security("api_key")
                         .param().name("id").type(RestParamType.path).description("The id
of the user to get").endParam()
                         .param().name("date").type(RestParamType.path).description("The date").dataFormat("date").endParam()
                         .to("bean:userService?method=getUser(${header.id})")
 
                     .put().description("Updates or create a user").type(User.class)
+                        // setup security for this rest verb
+                        .security("petstore_auth", "write:pets,read:pets")
                         .param().name("body").type(RestParamType.body).description("The user
to update or create").endParam()
                         .to("bean:userService?method=updateUser")
 
@@ -94,6 +98,9 @@ public class RestSwaggerReaderModelApiSecurityTest extends CamelTestSupport
{
         assertTrue(json.contains("\"type\" : \"apiKey\","));
         assertTrue(json.contains("\"in\" : \"header\""));
         assertTrue(json.contains("\"host\" : \"localhost:8080\""));
+        assertTrue(json.contains("\"security\" : [ {"));
+        assertTrue(json.contains("\"petstore_auth\" : [ \"write:pets\", \"read:pets\" ]"));
+        assertTrue(json.contains("\"api_key\" : [ ]"));
         assertTrue(json.contains("\"description\" : \"The user returned\""));
         assertTrue(json.contains("\"$ref\" : \"#/definitions/User\""));
         assertTrue(json.contains("\"x-className\""));

-- 
To stop receiving notification emails like this one, please contact
davsclaus@apache.org.

Mime
View raw message