diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 1893e8965e..5c57b2b35e 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v2 - name: Cache Gradle packages - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: | ~/.gradle/caches @@ -46,7 +46,7 @@ jobs: - name: Create Github Draft Release id: create_release - uses: actions/create-release@v1.0.0 + uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 1490e1d7f6..13a2b8a265 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -22,7 +22,7 @@ jobs: distribution: temurin # Temurin is a distribution of adoptium java-version: 11 - uses: actions/checkout@v3 - - uses: aws-actions/configure-aws-credentials@v1 + - uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: ${{ secrets.PUBLISH_SNAPSHOTS_ROLE }} aws-region: us-east-1 diff --git a/build.gradle b/build.gradle index 815d3aa840..f8f9b701ad 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,7 @@ plugins { id 'maven-publish' id 'com.diffplug.spotless' version '6.20.0' id 'checkstyle' - id 'com.netflix.nebula.ospackage' version "11.3.0" + id 'com.netflix.nebula.ospackage' version "11.4.0" id "org.gradle.test-retry" version "1.5.4" id 'eclipse' id "com.github.spotbugs" version "5.0.14" @@ -578,7 +578,7 @@ dependencies { testImplementation "org.opensaml:opensaml-messaging-impl:${open_saml_version}" - implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'org.apache.commons:commons-lang3:3.13.0' testImplementation "org.opensearch:common-utils:${common_utils_version}" testImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}" testImplementation "org.opensearch:opensearch-ssl-config:${opensearch_version}" @@ -610,7 +610,7 @@ dependencies { // JUnit build requirement testCompileOnly 'org.apiguardian:apiguardian-api:1.1.2' // Kafka test execution - testRuntimeOnly 'org.springframework.retry:spring-retry:1.3.3' + testRuntimeOnly 'org.springframework.retry:spring-retry:1.3.4' testRuntimeOnly ('org.springframework:spring-core:5.3.27') { exclude(group:'org.springframework', module: 'spring-jcl' ) } diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java b/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java index 0966a3f3ac..84dc7f8c19 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java @@ -232,7 +232,7 @@ public DlsGetEvaluator(final Query dlsQuery, final LeafReader in, boolean applyD // https://github.com/apache/lucene-solr/blob/branch_6_3/lucene/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java final IndexSearcher searcher = new IndexSearcher(DlsFlsFilterLeafReader.this); searcher.setQueryCache(null); - final Weight preserveWeight = searcher.createWeight(dlsQuery, ScoreMode.COMPLETE_NO_SCORES, 1f); + final Weight preserveWeight = searcher.rewrite(dlsQuery).createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1f); final int maxDoc = in.maxDoc(); final FixedBitSet bits = new FixedBitSet(maxDoc); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java index d43a804d47..e2badef14c 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java @@ -35,6 +35,13 @@ protected void populateData(Client tc) { new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 1500}", XContentType.JSON) ).actionGet(); + tc.index( + new IndexRequest("terms").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"foo\": \"bar\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("terms").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"foo\": \"baz\"}", XContentType.JSON) + ).actionGet(); + try { Thread.sleep(3000); } catch (InterruptedException e) { @@ -44,6 +51,7 @@ protected void populateData(Client tc) { System.out.println("q"); System.out.println(Strings.toString(XContentType.JSON, tc.search(new SearchRequest().indices(".opendistro_security")).actionGet())); tc.search(new SearchRequest().indices("deals")).actionGet(); + tc.search(new SearchRequest().indices("terms")).actionGet(); } @Test @@ -251,6 +259,32 @@ public void testDls() throws Exception { } + @Test + public void testDlsWithTermsQuery() throws Exception { + + setup(); + + HttpResponse res; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/terms/_search?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); + Assert.assertEquals(res.getTextFromJsonBody("/hits/total/value"), "1"); + Assert.assertEquals(res.getTextFromJsonBody("/_shards/failed"), "0"); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/terms/_doc/0", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); + Assert.assertEquals(res.getTextFromJsonBody("/_source/foo"), "bar"); + + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + rh.executeGetRequest("/terms/_doc/1", encodeBasicHeader("dept_manager", "password")).getStatusCode() + ); + } + @Test public void testNonDls() throws Exception { diff --git a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java index 87ffa06da7..7eefd22273 100644 --- a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java @@ -45,6 +45,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import org.apache.commons.lang3.StringUtils; import org.apache.hc.client5.http.async.methods.SimpleHttpRequest; @@ -433,6 +434,22 @@ public boolean isJsonContentType() { return ct.contains("application/json"); } + public String getTextFromJsonBody(String jsonPointer) { + return getJsonNodeAt(jsonPointer).asText(); + } + + private JsonNode getJsonNodeAt(String jsonPointer) { + try { + return toJsonNode().at(jsonPointer); + } catch (IOException e) { + throw new IllegalArgumentException("Cound not convert response body to JSON node ", e); + } + } + + private JsonNode toJsonNode() throws JsonProcessingException, IOException { + return DefaultObjectMapper.objectMapper.readTree(getBody()); + } + public SimpleHttpResponse getInner() { return inner; } diff --git a/src/test/resources/dlsfls/roles.yml b/src/test/resources/dlsfls/roles.yml index c692f73ceb..185116e2bb 100644 --- a/src/test/resources/dlsfls/roles.yml +++ b/src/test/resources/dlsfls/roles.yml @@ -2482,3 +2482,12 @@ logs_index_with_dls: masked_fields: null allowed_actions: - "OPENDISTRO_SECURITY_READ" + +terms_index_with_dls: + index_permissions: + - index_patterns: + - "terms" + dls: "{ \"terms\": { \"foo\" : [\"bar\"] } }" + masked_fields: null + allowed_actions: + - "OPENDISTRO_SECURITY_READ" diff --git a/src/test/resources/dlsfls/roles_mapping.yml b/src/test/resources/dlsfls/roles_mapping.yml index 27cf71c3bb..a37299908d 100644 --- a/src/test/resources/dlsfls/roles_mapping.yml +++ b/src/test/resources/dlsfls/roles_mapping.yml @@ -247,3 +247,7 @@ opendistro_security_mapped: logs_index_with_dls: users: - dept_manager + +terms_index_with_dls: + users: + - dept_manager