From faeb6fa507a7150d5111dbf78c4fb36f27e116ac Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Fri, 8 Dec 2023 16:59:15 +0100 Subject: [PATCH 01/10] add API endpoint for getting file definitions fixes #4508 --- apiary.apib | 84 +++++++++++++++++++ .../indexer/analysis/Definitions.java | 48 ++++++++++- .../web/api/v1/controller/FileController.java | 28 ++++++- .../api/v1/controller/FileControllerTest.java | 48 +++++++++-- 4 files changed, 201 insertions(+), 7 deletions(-) diff --git a/apiary.apib b/apiary.apib index b420f8b0ae1..e60e52702f5 100644 --- a/apiary.apib +++ b/apiary.apib @@ -145,6 +145,90 @@ The `Content-type` header of the reply will be set accordingly. genre as identified by analyzer, could be PLAIN, XREFABLE, IMAGE, DATA, HTML +## File definitions [/file/defs{?path}] + +### get file definitions [GET] + ++ Parameters + + path (string) - path of file, relative to source root + ++ Response 200 (application/json) + + Body + + [ + { + "type": "function", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,", + "symbol": "AES_cbc_encrypt", + "lineStart": 5, + "lineEnd": 20, + "line": 20, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "in", + "lineStart": 21, + "lineEnd": 44, + "line": 20, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "out", + "lineStart": 46, + "lineEnd": 64, + "line": 20, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "len", + "lineStart": 21, + "lineEnd": 31, + "line": 21, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "key", + "lineStart": 33, + "lineEnd": 51, + "line": 21, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "ivec", + "lineStart": 21, + "lineEnd": 40, + "line": 22, + "namespace": null + }, + { + "type": "argument", + "signature": "(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "text": "AES_cbc_encrypt(const unsigned char * in,unsigned char * out,size_t len,const AES_KEY * key,unsigned char * ivec,const int enc)", + "symbol": "enc", + "lineStart": 42, + "lineEnd": 55, + "line": 22, + "namespace": null + } + ] + + ## History [/history{?path,withFiles,start,max}] ### get history entries [GET] diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java index 08b0cdc81d3..5501a6261d9 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java @@ -24,6 +24,7 @@ package org.opengrok.indexer.analysis; import org.jetbrains.annotations.Nullable; +import org.opengrok.indexer.util.DTOElement; import org.opengrok.indexer.util.WhitelistObjectInputFilter; import java.io.ByteArrayInputStream; @@ -206,39 +207,80 @@ public static class Tag implements Serializable { private static final long serialVersionUID = 1217869075425651465L; + public int getLine() { + return line; + } + + public String getSymbol() { + return symbol; + } + /** * Line number of the tag. */ + @DTOElement public final int line; /** * The symbol used in the definition. */ + @DTOElement public final String symbol; + + public String getType() { + return type; + } + + public String getText() { + return text; + } + + public String getNamespace() { + return namespace; + } + + public String getSignature() { + return signature; + } + + public int getLineStart() { + return lineStart; + } + + public int getLineEnd() { + return lineEnd; + } + /** * The type of the tag. */ + @DTOElement public final String type; /** * The full line on which the definition occurs. */ + @DTOElement public final String text; /** * Namespace/class of tag definition. */ + @DTOElement public final String namespace; /** * Scope of tag definition. */ + @DTOElement public final String signature; /** * The starting offset (possibly approximate) of {@link #symbol} from * the start of the line. */ + @DTOElement public final int lineStart; /** * The ending offset (possibly approximate) of {@link #symbol} from * the start of the line. */ + @DTOElement public final int lineEnd; /** @@ -246,7 +288,11 @@ public static class Tag implements Serializable { */ private transient boolean used; - protected Tag(int line, String symbol, String type, String text, + public Tag() { + this(0, null, null, null, null, null, 0, 0); + } + + public Tag(int line, String symbol, String type, String text, String namespace, String signature, int lineStart, int lineEnd) { this.line = line; diff --git a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java index 149239cd1c2..304e468e62b 100644 --- a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java +++ b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java @@ -18,7 +18,7 @@ */ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (c) 2020, Chris Fraire . */ package org.opengrok.web.api.v1.controller; @@ -35,9 +35,12 @@ import org.apache.lucene.document.Document; import org.apache.lucene.queryparser.classic.ParseException; import org.opengrok.indexer.analysis.AbstractAnalyzer; +import org.opengrok.indexer.analysis.Definitions; +import org.opengrok.indexer.index.IndexDatabase; import org.opengrok.indexer.search.QueryBuilder; import org.opengrok.web.api.v1.filter.CorsEnable; import org.opengrok.web.api.v1.filter.PathAuthorized; +import org.opengrok.web.util.DTOUtil; import org.opengrok.web.util.NoPathParameterException; import java.io.File; @@ -45,6 +48,10 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import static org.opengrok.indexer.index.IndexDatabase.getDocument; import static org.opengrok.web.util.FileUtil.toFile; @@ -54,6 +61,8 @@ public class FileController { public static final String PATH = "file"; + + private StreamingOutput transfer(File file) throws FileNotFoundException { if (!file.exists()) { throw new FileNotFoundException(String.format("file %s does not exist", file)); @@ -141,4 +150,21 @@ public String getGenre(@Context HttpServletRequest request, return genre.toString(); } + + @GET + @CorsEnable + @PathAuthorized + @Path("/defs") + @Produces(MediaType.APPLICATION_JSON) + public List getDefinitions(@Context HttpServletRequest request, + @Context HttpServletResponse response, + @QueryParam("path") final String path) + throws IOException, NoPathParameterException, ParseException, ClassNotFoundException { + + File file = toFile(path); + Definitions defs = IndexDatabase.getDefinitions(file); + return Optional.ofNullable(defs). + map(Definitions::getTags).orElse(Collections.emptyList()). + stream().map(DTOUtil::createDTO).collect(Collectors.toList()); + } } diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index dee478a89e7..abfa3097acc 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -18,30 +18,41 @@ */ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (c) 2020, Chris Fraire . */ package org.opengrok.web.api.v1.controller; -import jakarta.ws.rs.core.Application; -import org.glassfish.jersey.server.ResourceConfig; +import jakarta.ws.rs.core.GenericType; +import org.glassfish.jersey.servlet.ServletContainer; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.ServletDeploymentContext; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.opengrok.indexer.analysis.Definitions; import org.opengrok.indexer.configuration.RuntimeEnvironment; import org.opengrok.indexer.history.HistoryGuru; import org.opengrok.indexer.history.RepositoryFactory; import org.opengrok.indexer.index.Indexer; import org.opengrok.indexer.util.TestRepository; +import org.opengrok.web.api.v1.RestApp; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; class FileControllerTest extends OGKJerseyTest { @@ -50,10 +61,16 @@ class FileControllerTest extends OGKJerseyTest { private TestRepository repository; @Override - protected Application configure() { - return new ResourceConfig(FileController.class); + protected DeploymentContext configureDeployment() { + return ServletDeploymentContext.forServlet(new ServletContainer(new RestApp())).build(); } + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return new GrizzlyWebTestContainerFactory(); + } + + @BeforeEach @Override public void setUp() throws Exception { @@ -113,4 +130,25 @@ void testFileGenre() { .get(String.class); assertEquals("PLAIN", genre); } + + @Test + void testFileDefinitions() { + final String path = "git/main.c"; + GenericType> type = new GenericType<>() { + }; + List defs = target("file") + .path("defs") + .queryParam("path", path) + .request() + .get(type); + assertFalse(defs.isEmpty()); + assertAll(() -> assertFalse(defs.stream().map(Definitions.Tag::getType).anyMatch(Objects::isNull)), + () -> assertFalse(defs.stream().map(Definitions.Tag::getSymbol).anyMatch(Objects::isNull)), + () -> assertFalse(defs.stream().map(Definitions.Tag::getText).anyMatch(Objects::isNull)), + () -> assertFalse(defs.stream().filter(e -> !e.getType().equals("local")). + map(Definitions.Tag::getSignature).anyMatch(Objects::isNull)), + () -> assertFalse(defs.stream().map(Definitions.Tag::getLine).anyMatch(e -> e <= 0)), + () -> assertFalse(defs.stream().map(Definitions.Tag::getLineStart).anyMatch(e -> e <= 0)), + () -> assertFalse(defs.stream().map(Definitions.Tag::getLineEnd).anyMatch(e -> e <= 0))); + } } From e74843402fb9465a1cd4255c2f626f2a37f644cb Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Fri, 8 Dec 2023 17:19:44 +0100 Subject: [PATCH 02/10] bump year --- .../main/java/org/opengrok/indexer/analysis/Definitions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java index 5501a6261d9..f9217592ea6 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java @@ -18,7 +18,7 @@ */ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (c) 2018, Chris Fraire . */ package org.opengrok.indexer.analysis; From 7c3f7979fd3ff77f898f08f7aa50a9ba23725793 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Fri, 8 Dec 2023 17:21:02 +0100 Subject: [PATCH 03/10] limit constructor visibility --- .../main/java/org/opengrok/indexer/analysis/Definitions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java index f9217592ea6..6c26ecb04a0 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Definitions.java @@ -288,11 +288,11 @@ public int getLineEnd() { */ private transient boolean used; - public Tag() { + protected Tag() { this(0, null, null, null, null, null, 0, 0); } - public Tag(int line, String symbol, String type, String text, + protected Tag(int line, String symbol, String type, String text, String namespace, String signature, int lineStart, int lineEnd) { this.line = line; From d53dba1f8ba3598336f7397c5d9a9b601b56e488 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Mon, 11 Dec 2023 15:53:58 +0100 Subject: [PATCH 04/10] add negative test case --- .../api/v1/controller/FileControllerTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index abfa3097acc..92fcc963b6b 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -37,12 +37,14 @@ import org.opengrok.indexer.configuration.RuntimeEnvironment; import org.opengrok.indexer.history.HistoryGuru; import org.opengrok.indexer.history.RepositoryFactory; +import org.opengrok.indexer.index.IndexDatabase; import org.opengrok.indexer.index.Indexer; import org.opengrok.indexer.util.TestRepository; import org.opengrok.web.api.v1.RestApp; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; @@ -53,6 +55,8 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; class FileControllerTest extends OGKJerseyTest { @@ -151,4 +155,24 @@ void testFileDefinitions() { () -> assertFalse(defs.stream().map(Definitions.Tag::getLineStart).anyMatch(e -> e <= 0)), () -> assertFalse(defs.stream().map(Definitions.Tag::getLineEnd).anyMatch(e -> e <= 0))); } + + /** + * Negative test case for file definitions API endpoint for a file that exists under the source root, + * however does not have matching document in the respective index database. + */ + @Test + void testFileDefinitionsNull() throws Exception { + final String path = "git/extra.file"; + Path createdPath = Files.createFile(Path.of(env.getSourceRootPath(), path)); + // Assumes that the API endpoint indeed calls IndexDatabase#getDefinitions() + assertNull(IndexDatabase.getDefinitions(createdPath.toFile())); + GenericType> type = new GenericType<>() { + }; + List defs = target("file") + .path("defs") + .queryParam("path", path) + .request() + .get(type); + assertTrue(defs.isEmpty()); + } } From bcf8ce730a9a9856d37a35472728a4d5f6b64d4e Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 16:53:38 +0100 Subject: [PATCH 05/10] add authorization test --- .../api/v1/controller/FileControllerTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index 92fcc963b6b..fb036faa58e 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -24,6 +24,7 @@ package org.opengrok.web.api.v1.controller; import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.Response; import org.glassfish.jersey.servlet.ServletContainer; import org.glassfish.jersey.test.DeploymentContext; import org.glassfish.jersey.test.ServletDeploymentContext; @@ -34,6 +35,10 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opengrok.indexer.analysis.Definitions; +import org.opengrok.indexer.authorization.AuthControlFlag; +import org.opengrok.indexer.authorization.AuthorizationFramework; +import org.opengrok.indexer.authorization.AuthorizationPlugin; +import org.opengrok.indexer.authorization.AuthorizationStack; import org.opengrok.indexer.configuration.RuntimeEnvironment; import org.opengrok.indexer.history.HistoryGuru; import org.opengrok.indexer.history.RepositoryFactory; @@ -42,11 +47,15 @@ import org.opengrok.indexer.util.TestRepository; import org.opengrok.web.api.v1.RestApp; +import java.io.File; import java.io.IOException; +import java.net.URL; +import java.net.http.HttpResponse; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -55,6 +64,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -175,4 +185,34 @@ void testFileDefinitionsNull() throws Exception { .get(type); assertTrue(defs.isEmpty()); } + + /** + * Make sure that file definitions API performs authorization check. + */ + @Test + void testFileDefinitionsNotAuthorized() throws Exception { + AuthorizationStack stack = new AuthorizationStack(AuthControlFlag.REQUIRED, "stack"); + stack.add(new AuthorizationPlugin(AuthControlFlag.REQUIRED, "opengrok.auth.plugin.FalsePlugin")); + URL pluginsURL = AuthorizationFramework.class.getResource("/authorization/plugins/testplugins.jar"); + assertNotNull(pluginsURL); + Path pluginsPath = Paths.get(pluginsURL.toURI()); + assertNotNull(pluginsPath); + File pluginDirectory = pluginsPath.toFile().getParentFile(); + assertNotNull(pluginDirectory); + assertTrue(pluginDirectory.isDirectory()); + AuthorizationFramework framework = new AuthorizationFramework(pluginDirectory.getPath(), stack); + framework.setLoadClasses(false); // to avoid noise when loading classes of other tests + framework.reload(); + env.setAuthorizationFramework(framework); + + final String path = "git/main.c"; + Response response = target("file") + .path("defs") + .queryParam("path", path) + .request().get(); + assertEquals(Response.Status.FORBIDDEN.getStatusCode(), response.getStatus()); + + // Cleanup. + env.setAuthorizationFramework(null); + } } From 06fcb1aae41c74a568a21d9285f14d8b7d6e3241 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 16:55:51 +0100 Subject: [PATCH 06/10] remove unused imports --- .../org/opengrok/web/api/v1/controller/FileControllerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index fb036faa58e..8c1a2f1fb25 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -50,12 +50,10 @@ import java.io.File; import java.io.IOException; import java.net.URL; -import java.net.http.HttpResponse; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; From 45bc60bf139f2fcf82a5e93faa85acd5f16690aa Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 16:59:25 +0100 Subject: [PATCH 07/10] change to flatMap -> no need to use orElse() --- .../opengrok/web/api/v1/controller/FileController.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java index 304e468e62b..35d9b002753 100644 --- a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java +++ b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java @@ -48,9 +48,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Collection; import java.util.stream.Collectors; import static org.opengrok.indexer.index.IndexDatabase.getDocument; @@ -164,7 +164,10 @@ public List getDefinitions(@Context HttpServletRequest request, File file = toFile(path); Definitions defs = IndexDatabase.getDefinitions(file); return Optional.ofNullable(defs). - map(Definitions::getTags).orElse(Collections.emptyList()). - stream().map(DTOUtil::createDTO).collect(Collectors.toList()); + map(Definitions::getTags). + stream(). + flatMap(Collection::stream). + map(DTOUtil::createDTO). + collect(Collectors.toList()); } } From 39702b0d5fa659173bf7c84ff3d1926f1038d10a Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 17:00:15 +0100 Subject: [PATCH 08/10] reorder imports --- .../java/org/opengrok/web/api/v1/controller/FileController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java index 35d9b002753..981d24fc844 100644 --- a/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java +++ b/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/FileController.java @@ -48,9 +48,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.Collection; import java.util.List; import java.util.Optional; -import java.util.Collection; import java.util.stream.Collectors; import static org.opengrok.indexer.index.IndexDatabase.getDocument; From 13da9bb7508d30ff39b46fa587674afa2ba0ef46 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 17:06:15 +0100 Subject: [PATCH 09/10] reuse the path --- .../web/api/v1/controller/FileControllerTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index 8c1a2f1fb25..ed761ca1059 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -70,6 +70,8 @@ class FileControllerTest extends OGKJerseyTest { private final RuntimeEnvironment env = RuntimeEnvironment.getInstance(); + private static final String validPath = "git/main.c"; + private TestRepository repository; @Override @@ -134,10 +136,9 @@ void testFileContent() throws IOException { @Test void testFileGenre() { - final String path = "git/main.c"; String genre = target("file") .path("genre") - .queryParam("path", path) + .queryParam("path", validPath) .request() .get(String.class); assertEquals("PLAIN", genre); @@ -145,12 +146,11 @@ void testFileGenre() { @Test void testFileDefinitions() { - final String path = "git/main.c"; GenericType> type = new GenericType<>() { }; List defs = target("file") .path("defs") - .queryParam("path", path) + .queryParam("path", validPath) .request() .get(type); assertFalse(defs.isEmpty()); @@ -203,10 +203,9 @@ void testFileDefinitionsNotAuthorized() throws Exception { framework.reload(); env.setAuthorizationFramework(framework); - final String path = "git/main.c"; Response response = target("file") .path("defs") - .queryParam("path", path) + .queryParam("path", validPath) .request().get(); assertEquals(Response.Status.FORBIDDEN.getStatusCode(), response.getStatus()); From 8ac93db0d15de2ae62bae29bef5244f3971c1015 Mon Sep 17 00:00:00 2001 From: Vladimir Kotal Date: Tue, 12 Dec 2023 17:45:48 +0100 Subject: [PATCH 10/10] copy plugins to opengrok-web --- .../api/v1/controller/FileControllerTest.java | 2 +- opengrok-web/src/test/resources/testplugins.jar | Bin 0 -> 2040 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 opengrok-web/src/test/resources/testplugins.jar diff --git a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java index ed761ca1059..34ca34bb267 100644 --- a/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java +++ b/opengrok-web/src/test/java/org/opengrok/web/api/v1/controller/FileControllerTest.java @@ -191,7 +191,7 @@ void testFileDefinitionsNull() throws Exception { void testFileDefinitionsNotAuthorized() throws Exception { AuthorizationStack stack = new AuthorizationStack(AuthControlFlag.REQUIRED, "stack"); stack.add(new AuthorizationPlugin(AuthControlFlag.REQUIRED, "opengrok.auth.plugin.FalsePlugin")); - URL pluginsURL = AuthorizationFramework.class.getResource("/authorization/plugins/testplugins.jar"); + URL pluginsURL = getClass().getResource("/testplugins.jar"); assertNotNull(pluginsURL); Path pluginsPath = Paths.get(pluginsURL.toURI()); assertNotNull(pluginsPath); diff --git a/opengrok-web/src/test/resources/testplugins.jar b/opengrok-web/src/test/resources/testplugins.jar new file mode 100644 index 0000000000000000000000000000000000000000..5037550abbdc0fabbc7548288014b3aefd908e82 GIT binary patch literal 2040 zcmWIWW@Zs#;Nak3IJ($Bhye+3GO#fCx`sIFdiuHP|2xINz|0Wf&CUT*!30$nfK#&w zPz7AGucM!*n`>~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>gu43V0 zaQ&hqYVxOBXmW9o=$y~pT%Wpyyc@bqD|c4x1iK(XTFlM?XucB=gIvJHzyNfW^c-~O zGce>Aq~@g;()!oNh~g28+A zqp~dizF4{YN7_V%xa}JHonmgMdT<4CB^BR)e&_MV=eNJ>$1^6#PJ12Da#YJ?b-{8j zZx$_SC$7z&3vOhUb54<4$*6vzqxH%8w~76)W3PE{G!kEJ=e^s9d%C>1cbbM9%dCy3 zcKB?uT5x8T;@P0t9G>M{pIY1X6qtnOG?=Wdm@jLX)$8%nc$#Zorfu>p*`mW=Ppq9M zqhMga^H=S+;=i|^ym0dfRujHu7)*p?^B8WMK$a`(r)fC@=NbrSZF9&+q6uWOaG_zX?L}*seT#%p0>z*D37_k zZ&J0=##xdJRqkFqm7lX;E#NAn$Aa2dvK^*-iy0ZZLQ%DKx{jaw^NU{~Ct`HFWJ*1pT)kyX?T` ztMOoei@tRI8l$Qy4codTUHxN9pBhi_mk@ctbE`{V&zbkFk3@sj99Mq>`}SbIJ#U{Y zGIS>&n8tpt{h8qf*XIix%goeEr*daJx4G!rqxbaGyI*#H)@7CYh@K3MJyy#2L!kCz zqL;kC!u#qcNiUvl;woTW_p6R^-NDi=eQ%G2Y}>jr$Nb^6^xbbax5|U^8NcA4oxH$| zc8dj)%CV;}HC*Y-EitDUErCV*3pyj z%)QljyD>Fw?%boN^FJL`7nc9S_($W>OvyVr7nfwzSbl$RegDlFIobOEj11Wut~4;r zQq*bLAaSUcX=|xs>rDlLEw^l$g8i>f5T5ap<7E6Z_S$vvo9mjU?(CD=u;lob4L>~# zPxZLCC2U+Aq?f$*o95}W9m_oBxIMQ=O!_D*?rt$#!^~w~SbD##(JbkS7sPdX-&}J$ zWn%rH?e&>=a`M15w(ocFuk8P?e!SS_FRYe)%QWhQg;r?X*Y7_LxJY|Myzh!Inw;$ZOk>9D_=WRcoR~4i&iV4!*4Te`&u4a8c^%*K zqr{2tr~A5>4kyc%&Y2oJdG1;~_4bWAZ-pyzz%=$uw!_PowQ(vajeQ5DvCw(DibIm6 zg(B>%dG33JKdm~jy=Cu@o0o1^W#p$ztqM@SFz1VaVAU@p&NY7n+foCfYQ7oG%bynP z&&C~a@IL2#vwzW{Usf>Yb^w!DPU%nS3F{?79?0C9rLE^E`*w?b1KS*Te}nxE!D4&f zK0CdKOj|Cx&TzDjo^b1w>XzcZ7e;R3T&esq@^#@`gMwVSLc