diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8f51fdd..53c3d9b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,16 +34,16 @@ jobs: ref: '1.x' - name: Build OpenSearch working-directory: ./OpenSearch - run: ./gradlew publishToMavenLocal -Dbuild.snapshot=false + run: ./gradlew publishToMavenLocal # common-utils - name: Build and Test run: | - ./gradlew build -Dopensearch.version=1.1.0 + ./gradlew build -Dopensearch.version=1.1.0-SNAPSHOT - name: Publish to Maven Local run: | - ./gradlew publishToMavenLocal -Dopensearch.version=1.1.0 + ./gradlew publishToMavenLocal -Dopensearch.version=1.1.0-SNAPSHOT - name: Upload Coverage Report uses: codecov/codecov-action@v1 diff --git a/build.gradle b/build.gradle index 0f2b241a..d443ddf4 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { ext { opensearch_group = "org.opensearch" - opensearch_version = System.getProperty("opensearch.version", "1.1.0") + opensearch_version = System.getProperty("opensearch.version", "1.1.0-SNAPSHOT") kotlin_version = System.getProperty("kotlin.version", "1.4.32") } @@ -44,7 +44,17 @@ repositories { jcenter() } -group 'org.opensearch.commons' +ext { + isSnapshot = "true" == System.getProperty("build.snapshot", "true") +} + +allprojects { + group 'org.opensearch.commons' + version = opensearch_version - '-SNAPSHOT' + '.0' + if (isSnapshot) { + version += "-SNAPSHOT" + } +} sourceCompatibility = 1.8 @@ -146,8 +156,6 @@ task javadocJar(type: Jar) { from javadoc.destinationDir } -version '1.1.0.0' - publishing { publications { shadow(MavenPublication) { diff --git a/release-notes/opensearch-common-utils.release-notes-1.1.0.0.md b/release-notes/opensearch-common-utils.release-notes-1.1.0.0.md new file mode 100644 index 00000000..6f5a9071 --- /dev/null +++ b/release-notes/opensearch-common-utils.release-notes-1.1.0.0.md @@ -0,0 +1,8 @@ +## Version 1.1.0.0 Release Notes + +Compatible with OpenSearch 1.1.0 + +### Enhancements + + * Adding an utility method that allows consumers to set custom thread context property in InjectSecurity class ([#70](https://github.com/opensearch-project/common-utils/pull/70)) + diff --git a/src/main/java/org/opensearch/commons/InjectSecurity.java b/src/main/java/org/opensearch/commons/InjectSecurity.java index ab4f0323..2240ab60 100644 --- a/src/main/java/org/opensearch/commons/InjectSecurity.java +++ b/src/main/java/org/opensearch/commons/InjectSecurity.java @@ -160,6 +160,23 @@ public void injectRoles(final List roles) { } } + /** + * Allows one to set the property in threadContext if possible to the value provided. If not possible returns false. + * @param property + * @param value + * @return boolean + */ + public boolean injectProperty(final String property, final Object value) { + if (Strings.isNullOrEmpty(property) || value == null || threadContext.getTransient(property) != null) { + log.debug("{}, InjectSecurity - cannot inject property: {}", Thread.currentThread().getName(), id); + return false; + } else { + threadContext.putTransient(property, value); + log.debug("{}, InjectSecurity - inject property: {}", Thread.currentThread().getName(), id); + return true; + } + } + @Override public void close() { if (ctx != null) { diff --git a/src/test/java/org/opensearch/commons/InjectSecurityTest.java b/src/test/java/org/opensearch/commons/InjectSecurityTest.java index 0f6e0c83..a9073d93 100644 --- a/src/test/java/org/opensearch/commons/InjectSecurityTest.java +++ b/src/test/java/org/opensearch/commons/InjectSecurityTest.java @@ -27,13 +27,16 @@ package org.opensearch.commons; 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; import static org.opensearch.commons.ConfigConstants.INJECTED_USER; import static org.opensearch.commons.ConfigConstants.OPENSEARCH_SECURITY_INJECTED_ROLES; import static org.opensearch.commons.ConfigConstants.OPENSEARCH_SECURITY_USE_INJECTED_USER_FOR_PLUGINS; import java.util.Arrays; +import java.util.Map; import org.junit.jupiter.api.Test; import org.opensearch.common.settings.Settings; @@ -102,4 +105,55 @@ public void testInjectUser() { assertEquals("plugin", threadContext.getTransient("ctx.name")); assertNull(threadContext.getTransient(INJECTED_USER)); } + + @Test + public void testInjectProperty() { + Settings settings = Settings.builder().put(OPENSEARCH_SECURITY_USE_INJECTED_USER_FOR_PLUGINS, false).build(); + Settings headerSettings = Settings.builder().put("request.headers.default", "1").build(); + ThreadContext threadContext = new ThreadContext(headerSettings); + threadContext.putHeader("name", "opendistro"); + threadContext.putTransient("ctx.name", "plugin"); + + assertEquals("1", threadContext.getHeader("default")); + assertEquals("opendistro", threadContext.getHeader("name")); + assertEquals("plugin", threadContext.getTransient("ctx.name")); + + try (InjectSecurity helper = new InjectSecurity("test-name", settings, threadContext)) { + helper.inject("joe", Arrays.asList("ops-role", "logs-role")); + assertEquals("1", threadContext.getHeader("default")); + assertEquals("opendistro", threadContext.getHeader("name")); + assertEquals("plugin", threadContext.getTransient("ctx.name")); + assertNotNull(threadContext.getTransient(OPENSEARCH_SECURITY_INJECTED_ROLES)); + // cannot inject property that is already set + assertFalse(helper.injectProperty(OPENSEARCH_SECURITY_INJECTED_ROLES, "new value")); + assertEquals("plugin|ops-role,logs-role", threadContext.getTransient(OPENSEARCH_SECURITY_INJECTED_ROLES)); + // cannot inject invalid property/value + assertFalse(helper.injectProperty("", "new value")); + assertFalse(helper.injectProperty(null, "new value")); + assertFalse(helper.injectProperty("property", null)); + // can inject non-set valid properties + assertTrue(helper.injectProperty("property1", true)); + assertTrue(helper.injectProperty("property2", "some value")); + assertTrue(helper.injectProperty("property3", "")); + assertTrue(helper.injectProperty("property4", Map.of("key", "value"))); + // verify the set properties are not null and equal to what was set + assertNull(threadContext.getTransient("property")); + assertNotNull(threadContext.getTransient("property1")); + assertEquals(true, threadContext.getTransient("property1")); + assertNotNull(threadContext.getTransient("property2")); + assertEquals("some value", threadContext.getTransient("property2")); + assertNotNull(threadContext.getTransient("property3")); + assertEquals("", threadContext.getTransient("property3")); + assertNotNull(threadContext.getTransient("property4")); + assertEquals(Map.of("key", "value"), threadContext.getTransient("property4")); + } + assertEquals("1", threadContext.getHeader("default")); + assertEquals("opendistro", threadContext.getHeader("name")); + assertEquals("plugin", threadContext.getTransient("ctx.name")); + assertNull(threadContext.getTransient(OPENSEARCH_SECURITY_INJECTED_ROLES)); + assertNull(threadContext.getTransient("property1")); + assertNull(threadContext.getTransient("property2")); + assertNull(threadContext.getTransient("property3")); + assertNull(threadContext.getTransient("property4")); + } }