+ * The content of this file is subject to the terms of the Apache 2.0 open + * source license available at https://www.opensource.org/licenses/apache-2.0 + *
+ * Restlet is a registered trademark of QlikTech International AB. + */ +package org.restlet.ext.openapi.example; + +import java.util.Arrays; +import org.restlet.data.ChallengeScheme; +import org.restlet.ext.openapi.OpenApiApplication; +import org.restlet.routing.Router; +import org.restlet.security.ChallengeAuthenticator; +import org.restlet.security.MapVerifier; + +public class BasicAuthenticationRootRouterExample { + + public static class BasicAuthenticationRootRouterApplication extends OpenApiApplication { + @Override + public org.restlet.Restlet createInboundRoot() { + var router = new Router(getContext()); + router.attach("/api", booksRouter()); + + var authenticator = + new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, "realm"); + authenticator.setVerifier(new TestVerifier()); + authenticator.setNext(router); + + return authenticator; + } + + private Router booksRouter() { + var router = new Router(getContext()); + router.attach("/books", BookResources.BooksResource.class); + router.attach("/books/{bookId}", BookResources.BookResource.class); + return router; + } + } + + public static class TestVerifier extends MapVerifier { + public TestVerifier() { + getLocalSecrets().put("login", "password".toCharArray()); + } + + @Override + public int verify(String identifier, char[] inputSecret) { + try { + return super.verify(identifier, inputSecret); + } finally { + // Clear secret from memory as soon as possible + Arrays.fill(inputSecret, '\000'); + } + } + } +} diff --git a/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BasicAuthenticationSubRouterExample.java b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BasicAuthenticationSubRouterExample.java new file mode 100644 index 0000000000..667e8c2d2f --- /dev/null +++ b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BasicAuthenticationSubRouterExample.java @@ -0,0 +1,58 @@ +/** + * Copyright 2005-2026 Qlik + *
+ * The content of this file is subject to the terms of the Apache 2.0 open + * source license available at https://www.opensource.org/licenses/apache-2.0 + *
+ * Restlet is a registered trademark of QlikTech International AB. + */ +package org.restlet.ext.openapi.example; + +import java.util.Arrays; +import org.restlet.data.ChallengeScheme; +import org.restlet.ext.openapi.OpenApiApplication; +import org.restlet.routing.Router; +import org.restlet.security.ChallengeAuthenticator; +import org.restlet.security.MapVerifier; + +public class BasicAuthenticationSubRouterExample { + + public static class BasicAuthenticationSubRouterApplication extends OpenApiApplication { + @Override + public org.restlet.Restlet createInboundRoot() { + + var authenticator = + new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, "realm"); + authenticator.setVerifier(new TestVerifier()); + authenticator.setNext(booksRouter()); + + var router = new Router(getContext()); + router.attach("/api", authenticator); + + return router; + } + + private Router booksRouter() { + var router = new Router(getContext()); + router.attach("/books", BookResources.BooksResource.class); + router.attach("/books/{bookId}", BookResources.BookResource.class); + return router; + } + } + + public static class TestVerifier extends MapVerifier { + public TestVerifier() { + getLocalSecrets().put("login", "password".toCharArray()); + } + + @Override + public int verify(String identifier, char[] inputSecret) { + try { + return super.verify(identifier, inputSecret); + } finally { + // Clear secret from memory as soon as possible + Arrays.fill(inputSecret, '\000'); + } + } + } +} diff --git a/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/LibraryExample.java b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BookResources.java similarity index 86% rename from org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/LibraryExample.java rename to org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BookResources.java index 0657b8c09a..06329ec01f 100644 --- a/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/LibraryExample.java +++ b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/BookResources.java @@ -6,7 +6,7 @@ *
* Restlet is a registered trademark of QlikTech International AB.
*/
-package org.restlet.ext.openapi;
+package org.restlet.ext.openapi.example;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -22,9 +22,8 @@
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
-import org.restlet.routing.Router;
-public class LibraryExample {
+public class BookResources {
private static final List
+ * The content of this file is subject to the terms of the Apache 2.0 open
+ * source license available at https://www.opensource.org/licenses/apache-2.0
+ *
+ * Restlet is a registered trademark of QlikTech International AB.
+ */
+package org.restlet.ext.openapi.example;
+
+import org.restlet.ext.openapi.OpenApiApplication;
+import org.restlet.routing.Router;
+
+public class LibraryExample {
+
+ public static class LibraryApplication extends OpenApiApplication {
+ @Override
+ public org.restlet.Restlet createInboundRoot() {
+ var router = new Router(getContext());
+ router.attach("/books", BookResources.BooksResource.class);
+ router.attach("/books/{bookId}", BookResources.BookResource.class);
+ return router;
+ }
+ }
+}
diff --git a/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/SubRouterExample.java b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/SubRouterExample.java
new file mode 100644
index 0000000000..56095ced90
--- /dev/null
+++ b/org.restlet.ext.openapi/src/test/java/org/restlet/ext/openapi/example/SubRouterExample.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2005-2026 Qlik
+ *
+ * The content of this file is subject to the terms of the Apache 2.0 open
+ * source license available at https://www.opensource.org/licenses/apache-2.0
+ *
+ * Restlet is a registered trademark of QlikTech International AB.
+ */
+package org.restlet.ext.openapi.example;
+
+import org.restlet.ext.openapi.OpenApiApplication;
+import org.restlet.routing.Router;
+
+public class SubRouterExample {
+
+ public static class SubRouterApplication extends OpenApiApplication {
+ @Override
+ public org.restlet.Restlet createInboundRoot() {
+ var router = new Router(getContext());
+ router.attach("/api", apiRouter());
+ return router;
+ }
+
+ private Router apiRouter() {
+ var router = new Router(getContext());
+ router.attach("/items", booksRouter());
+ return router;
+ }
+
+ private Router booksRouter() {
+ var router = new Router(getContext());
+ router.attach("/books", BookResources.BooksResource.class);
+ router.attach("/books/{bookId}", BookResources.BookResource.class);
+ return router;
+ }
+ }
+}
diff --git a/org.restlet.ext.openapi/src/test/resources/basic-authentication-root-router-openapi.yaml b/org.restlet.ext.openapi/src/test/resources/basic-authentication-root-router-openapi.yaml
new file mode 100644
index 0000000000..b58e5b2bbd
--- /dev/null
+++ b/org.restlet.ext.openapi/src/test/resources/basic-authentication-root-router-openapi.yaml
@@ -0,0 +1,94 @@
+---
+openapi: "3.1.0"
+info:
+ title: "BasicAuthenticationRootRouter REST API"
+ version: "1.0.0"
+paths:
+ /api/books:
+ get:
+ summary: "Get a list of all books"
+ operationId: "getBooks"
+ parameters:
+ - name: "filter"
+ in: "query"
+ description: "Filter books"
+ required: false
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ type: "array"
+ items:
+ $ref: "#/components/schemas/Book"
+ security:
+ - HTTP_BASIC: []
+ post:
+ summary: "Add a new book"
+ operationId: "addBook"
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ responses:
+ "201":
+ description: "201 response"
+ headers:
+ Location:
+ style: "simple"
+ schema:
+ type: "string"
+ security:
+ - HTTP_BASIC: []
+ /api/books/{bookId}:
+ get:
+ summary: "Get a book by ID"
+ operationId: "getBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ security:
+ - HTTP_BASIC: []
+ delete:
+ summary: "Delete a book by ID"
+ operationId: "deleteBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ security:
+ - HTTP_BASIC: []
+components:
+ schemas:
+ Book:
+ type: "object"
+ properties:
+ id:
+ type: "string"
+ title:
+ type: "string"
+ author:
+ type: "string"
+ securitySchemes:
+ HTTP_BASIC:
+ type: "http"
+ scheme: "basic"
diff --git a/org.restlet.ext.openapi/src/test/resources/basic-authentication-subrouter-openapi.yaml b/org.restlet.ext.openapi/src/test/resources/basic-authentication-subrouter-openapi.yaml
new file mode 100644
index 0000000000..2d8b9981b3
--- /dev/null
+++ b/org.restlet.ext.openapi/src/test/resources/basic-authentication-subrouter-openapi.yaml
@@ -0,0 +1,94 @@
+---
+openapi: "3.1.0"
+info:
+ title: "BasicAuthenticationSubRouter REST API"
+ version: "1.0.0"
+paths:
+ /api/books:
+ get:
+ summary: "Get a list of all books"
+ operationId: "getBooks"
+ parameters:
+ - name: "filter"
+ in: "query"
+ description: "Filter books"
+ required: false
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ type: "array"
+ items:
+ $ref: "#/components/schemas/Book"
+ security:
+ - HTTP_BASIC: []
+ post:
+ summary: "Add a new book"
+ operationId: "addBook"
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ responses:
+ "201":
+ description: "201 response"
+ headers:
+ Location:
+ style: "simple"
+ schema:
+ type: "string"
+ security:
+ - HTTP_BASIC: []
+ /api/books/{bookId}:
+ get:
+ summary: "Get a book by ID"
+ operationId: "getBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ security:
+ - HTTP_BASIC: []
+ delete:
+ summary: "Delete a book by ID"
+ operationId: "deleteBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ security:
+ - HTTP_BASIC: []
+components:
+ schemas:
+ Book:
+ type: "object"
+ properties:
+ id:
+ type: "string"
+ title:
+ type: "string"
+ author:
+ type: "string"
+ securitySchemes:
+ HTTP_BASIC:
+ type: "http"
+ scheme: "basic"
diff --git a/org.restlet.ext.openapi/src/test/resources/sub-router-openapi.yaml b/org.restlet.ext.openapi/src/test/resources/sub-router-openapi.yaml
new file mode 100644
index 0000000000..5888fc5c8e
--- /dev/null
+++ b/org.restlet.ext.openapi/src/test/resources/sub-router-openapi.yaml
@@ -0,0 +1,82 @@
+---
+openapi: "3.1.0"
+info:
+ title: "SubRouter REST API"
+ version: "1.0.0"
+paths:
+ /api/items/books:
+ get:
+ summary: "Get a list of all books"
+ operationId: "getBooks"
+ parameters:
+ - name: "filter"
+ in: "query"
+ description: "Filter books"
+ required: false
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ type: "array"
+ items:
+ $ref: "#/components/schemas/Book"
+ post:
+ summary: "Add a new book"
+ operationId: "addBook"
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ responses:
+ "201":
+ description: "201 response"
+ headers:
+ Location:
+ style: "simple"
+ schema:
+ type: "string"
+ /api/items/books/{bookId}:
+ get:
+ summary: "Get a book by ID"
+ operationId: "getBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Book"
+ delete:
+ summary: "Delete a book by ID"
+ operationId: "deleteBook"
+ parameters:
+ - name: "bookId"
+ in: "path"
+ required: true
+ schema:
+ type: "string"
+ responses:
+ "200":
+ description: "Success"
+components:
+ schemas:
+ Book:
+ type: "object"
+ properties:
+ id:
+ type: "string"
+ title:
+ type: "string"
+ author:
+ type: "string"