From ccc5022d8f1b2d0c9fff22477430602e7b1898bc Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 17 Mar 2025 17:21:14 -0400 Subject: [PATCH 1/4] Introduces resource sharing and access control SPI Signed-off-by: Darshit Chanpura --- .github/workflows/ci.yml | 191 ++++++++--- .github/workflows/maven-publish.yml | 2 +- .gitignore | 4 - build.gradle | 92 +++-- scripts/build.sh | 4 + settings.gradle | 3 + spi/README.md | 167 +++++++++ spi/build.gradle | 86 +++++ .../security/spi/resources/Resource.java | 27 ++ .../spi/resources/ResourceAccessScope.java | 38 +++ .../spi/resources/ResourceParser.java | 29 ++ .../resources/ResourceSharingExtension.java | 35 ++ .../exceptions/ResourceSharingException.java | 60 ++++ .../security/spi/resources/package-info.java | 15 + .../spi/resources/sharing/CreatedBy.java | 88 +++++ .../spi/resources/sharing/Creator.java | 37 ++ .../spi/resources/sharing/Recipient.java | 31 ++ .../spi/resources/sharing/RecipientType.java | 24 ++ .../sharing/RecipientTypeRegistry.java | 39 +++ .../resources/sharing/ResourceSharing.java | 202 +++++++++++ .../spi/resources/sharing/ShareWith.java | 103 ++++++ .../resources/sharing/SharedWithScope.java | 169 +++++++++ .../spi/resources/CreatedByTests.java | 320 ++++++++++++++++++ .../resources/RecipientTypeRegistryTests.java | 43 +++ .../spi/resources/ShareWithTests.java | 284 ++++++++++++++++ .../security/OpenSearchSecurityPlugin.java | 17 +- .../security/support/ConfigConstants.java | 185 +++++----- 27 files changed, 2133 insertions(+), 162 deletions(-) create mode 100644 spi/README.md create mode 100644 spi/build.gradle create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/Resource.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/ResourceAccessScope.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/ResourceParser.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/ResourceSharingExtension.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/exceptions/ResourceSharingException.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/package-info.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/CreatedBy.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/Creator.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/Recipient.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientType.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientTypeRegistry.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/ResourceSharing.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/ShareWith.java create mode 100644 spi/src/main/java/org/opensearch/security/spi/resources/sharing/SharedWithScope.java create mode 100644 spi/src/test/java/org/opensearch/security/spi/resources/CreatedByTests.java create mode 100644 spi/src/test/java/org/opensearch/security/spi/resources/RecipientTypeRegistryTests.java create mode 100644 spi/src/test/java/org/opensearch/security/spi/resources/ShareWithTests.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a41062883..7b1b82e300 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,9 +32,35 @@ jobs: run: | echo "separateTestsNames=$(./gradlew listTasksAsJSON -q --console=plain | tail -n 1)" >> $GITHUB_OUTPUT + publish-components-to-maven-local: + runs-on: ubuntu-latest + steps: + - name: Set up JDK for build and test + uses: actions/setup-java@v4 + with: + distribution: temurin # Temurin is a distribution of adoptium + java-version: 21 + + - name: Checkout security + uses: actions/checkout@v4 + + - name: Publish components to Maven Local + run: | + ./gradlew clean \ + :opensearch-resource-sharing-spi:publishToMavenLocal \ + -Dbuild.snapshot=false + + - name: Cache artifacts for dependent jobs + uses: actions/cache@v4.2.2 + with: + path: ~/.m2/repository/org/opensearch/ + key: maven-local-${{ github.run_id }} + restore-keys: | + maven-local- + test: name: test - needs: generate-test-list + needs: [generate-test-list, publish-components-to-maven-local] strategy: fail-fast: false matrix: @@ -53,6 +79,14 @@ jobs: - name: Checkout security uses: actions/checkout@v4 + - name: Restore Maven Local Cache + uses: actions/cache@v4.2.2 + with: + path: ~/.m2/repository/org/opensearch/ + key: maven-local-${{ github.run_id }} + restore-keys: | + maven-local- + - name: Build and Test uses: gradle/gradle-build-action@v3 with: @@ -68,7 +102,7 @@ jobs: ./build/reports/ report-coverage: - needs: ["test", "integration-tests"] + needs: ["test", "integration-tests", "spi-tests"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -91,7 +125,6 @@ jobs: fail_ci_if_error: true verbose: true - integration-tests: name: integration-tests strategy: @@ -111,12 +144,20 @@ jobs: - name: Checkout security uses: actions/checkout@v4 - - name: Build and Test + - name: Restore Maven Local Cache + uses: actions/cache@v4.2.2 + with: + path: ~/.m2/repository/org/opensearch/ + key: maven-local-${{ github.run_id }} + restore-keys: | + maven-local- + + - name: Run Integration Tests uses: gradle/gradle-build-action@v3 with: cache-disabled: true arguments: | - integrationTest -Dbuild.snapshot=false + :integrationTest -Dbuild.snapshot=false - uses: actions/upload-artifact@v4 if: always() @@ -125,10 +166,52 @@ jobs: path: | ./build/reports/ + spi-tests: + name: spi-tests + needs: publish-components-to-maven-local + strategy: + fail-fast: false + matrix: + jdk: [21] + platform: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.platform }} + + steps: + - name: Set up JDK for build and test + uses: actions/setup-java@v4 + with: + distribution: temurin # Temurin is a distribution of adoptium + java-version: ${{ matrix.jdk }} + + - name: Checkout security + uses: actions/checkout@v4 + + - name: Restore Maven Local Cache + uses: actions/cache@v4.2.2 + with: + path: ~/.m2/repository/org/opensearch/ + key: maven-local-${{ github.run_id }} + restore-keys: | + maven-local- + + - name: Run SPI Tests + uses: gradle/gradle-build-action@v3 + with: + cache-disabled: true + arguments: | + :opensearch-resource-sharing-spi:test -Dbuild.snapshot=false + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: spi-${{ matrix.platform }}-JDK${{ matrix.jdk }}-reports + path: | + ./build/reports/ resource-tests: env: CI_ENVIRONMENT: resource-test + needs: publish-components-to-maven-local strategy: fail-fast: false matrix: @@ -146,12 +229,20 @@ jobs: - name: Checkout security uses: actions/checkout@v4 - - name: Build and Test + - name: Restore Maven Local Cache + uses: actions/cache@v4.2.2 + with: + path: ~/.m2/repository/org/opensearch/ + key: maven-local-${{ github.run_id }} + restore-keys: | + maven-local- + + - name: Run Resource Tests uses: gradle/gradle-build-action@v3 with: cache-disabled: true arguments: | - integrationTest -Dbuild.snapshot=false --tests org.opensearch.security.ResourceFocusedTests + :integrationTest -Dbuild.snapshot=false --tests org.opensearch.security.ResourceFocusedTests backward-compatibility-build: runs-on: ubuntu-latest @@ -214,40 +305,62 @@ jobs: build-artifact-names: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Setup Environment + uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - name: Configure Java + uses: actions/setup-java@v4 with: - distribution: temurin # Temurin is a distribution of adoptium + distribution: temurin java-version: 21 - - run: | - security_plugin_version=$(./gradlew properties -q | grep -E '^version:' | awk '{print $2}') - security_plugin_version_no_snapshot=$(echo $security_plugin_version | sed 's/-SNAPSHOT//g') - security_plugin_version_only_number=$(echo $security_plugin_version_no_snapshot | cut -d- -f1) - test_qualifier=alpha2 - - echo "SECURITY_PLUGIN_VERSION=$security_plugin_version" >> $GITHUB_ENV - echo "SECURITY_PLUGIN_VERSION_NO_SNAPSHOT=$security_plugin_version_no_snapshot" >> $GITHUB_ENV - echo "SECURITY_PLUGIN_VERSION_ONLY_NUMBER=$security_plugin_version_only_number" >> $GITHUB_ENV - echo "TEST_QUALIFIER=$test_qualifier" >> $GITHUB_ENV - - - run: | - echo ${{ env.SECURITY_PLUGIN_VERSION }} - echo ${{ env.SECURITY_PLUGIN_VERSION_NO_SNAPSHOT }} - echo ${{ env.SECURITY_PLUGIN_VERSION_ONLY_NUMBER }} - echo ${{ env.TEST_QUALIFIER }} - - - run: ./gradlew clean assemble && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION }}.zip - - - run: ./gradlew clean assemble -Dbuild.snapshot=false && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION_NO_SNAPSHOT }}.zip - - - run: ./gradlew clean assemble -Dbuild.snapshot=false -Dbuild.version_qualifier=${{ env.TEST_QUALIFIER }} && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION_ONLY_NUMBER }}-${{ env.TEST_QUALIFIER }}.zip - - - run: ./gradlew clean assemble -Dbuild.version_qualifier=${{ env.TEST_QUALIFIER }} && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION_ONLY_NUMBER }}-${{ env.TEST_QUALIFIER }}-SNAPSHOT.zip - - - run: ./gradlew clean publishPluginZipPublicationToZipStagingRepository && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION }}.zip && test -s ./build/distributions/opensearch-security-${{ env.SECURITY_PLUGIN_VERSION }}.pom - - - name: List files in the build directory if there was an error - run: ls -al ./build/distributions/ + - name: Build and Test Artifacts + run: | + # Set version variables + security_plugin_version=$(./gradlew properties -q | grep -E '^version:' | awk '{print $2}') + security_plugin_version_no_snapshot=$(echo $security_plugin_version | sed 's/-SNAPSHOT//g') + security_plugin_version_only_number=$(echo $security_plugin_version_no_snapshot | cut -d- -f1) + test_qualifier=alpha2 + + # Debug print versions + echo "Versions:" + echo $security_plugin_version + echo $security_plugin_version_no_snapshot + echo $security_plugin_version_only_number + echo $test_qualifier + + # Publish SPI + ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar + ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal -Dbuild.snapshot=false && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_no_snapshot-all.jar + ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-all.jar + ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal -Dbuild.version_qualifier=$test_qualifier && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT-all.jar + + + # Build artifacts + ./gradlew clean assemble && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version.zip && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version.jar + + ./gradlew clean assemble -Dbuild.snapshot=false && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version_no_snapshot.zip && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_no_snapshot.jar + + ./gradlew clean assemble -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version_only_number-$test_qualifier.zip && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier.jar + + ./gradlew clean assemble -Dbuild.version_qualifier=$test_qualifier && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.zip && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.jar + + ./gradlew clean publishPluginZipPublicationToZipStagingRepository && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version.zip && \ + test -s ./build/distributions/opensearch-security-$security_plugin_version.pom && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar + + ./gradlew clean publishShadowPublicationToMavenLocal && \ + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar + + - name: List files in build directory on failure if: failure() + run: ls -al ./*/build/libs/ ./build/distributions/ diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index d10fd67beb..42d07fbb0a 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -32,4 +32,4 @@ jobs: export SONATYPE_PASSWORD=$(aws secretsmanager get-secret-value --secret-id maven-snapshots-password --query SecretString --output text) echo "::add-mask::$SONATYPE_USERNAME" echo "::add-mask::$SONATYPE_PASSWORD" - ./gradlew publishPluginZipPublicationToSnapshotsRepository + ./gradlew --no-daemon publishPluginZipPublicationToSnapshotsRepository publishShadowPublicationToSnapshotsRepository diff --git a/.gitignore b/.gitignore index 6fbfafabac..5eb2da999f 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,3 @@ out/ build/ gradle-build/ .gradle/ - -# nodejs -node_modules/ -package-lock.json diff --git a/build.gradle b/build.gradle index c7ba88a881..9d803c03f2 100644 --- a/build.gradle +++ b/build.gradle @@ -500,6 +500,12 @@ configurations { force "org.checkerframework:checker-qual:3.49.1" force "ch.qos.logback:logback-classic:1.5.17" force "commons-io:commons-io:2.18.0" + force "com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.2" + force "org.hamcrest:hamcrest:2.2" + force "org.mockito:mockito-core:5.16.1" + force "net.bytebuddy:byte-buddy:1.15.11" + force "org.ow2.asm:asm:9.7.1" + force "com.google.j2objc:j2objc-annotations:3.0.0" } } @@ -507,6 +513,65 @@ configurations { integrationTestRuntimeOnly.extendsFrom runtimeOnly } +allprojects { + configurations { + integrationTestImplementation.extendsFrom implementation + compile.extendsFrom compileOnly + compile.extendsFrom testImplementation + } + dependencies { + // unit test framework + testImplementation 'org.hamcrest:hamcrest:2.2' + testImplementation 'junit:junit:4.13.2' + testImplementation "org.opensearch:opensearch:${opensearch_version}" + testImplementation "org.mockito:mockito-core:5.16.1" + + //integration test framework: + integrationTestImplementation('com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.2') { + exclude(group: 'junit', module: 'junit') + } + integrationTestImplementation 'junit:junit:4.13.2' + integrationTestImplementation("org.opensearch.plugin:reindex-client:${opensearch_version}"){ + exclude(group: 'org.slf4j', module: 'slf4j-api') + } + integrationTestImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}" + integrationTestImplementation 'commons-io:commons-io:2.18.0' + integrationTestImplementation "org.apache.logging.log4j:log4j-core:${versions.log4j}" + integrationTestImplementation "org.apache.logging.log4j:log4j-jul:${versions.log4j}" + integrationTestImplementation 'org.hamcrest:hamcrest:2.2' + integrationTestImplementation "org.bouncycastle:bcpkix-jdk18on:${versions.bouncycastle}" + integrationTestImplementation "org.bouncycastle:bcutil-jdk18on:${versions.bouncycastle}" + integrationTestImplementation('org.awaitility:awaitility:4.2.2') { + exclude(group: 'org.hamcrest', module: 'hamcrest') + } + integrationTestImplementation 'com.unboundid:unboundid-ldapsdk:4.0.14' + integrationTestImplementation "org.opensearch.plugin:mapper-size:${opensearch_version}" + integrationTestImplementation "org.apache.httpcomponents:httpclient-cache:4.5.14" + integrationTestImplementation "org.apache.httpcomponents:httpclient:4.5.14" + integrationTestImplementation "org.apache.httpcomponents:fluent-hc:4.5.14" + integrationTestImplementation "org.apache.httpcomponents:httpcore:4.4.16" + integrationTestImplementation "org.apache.httpcomponents:httpasyncclient:4.1.5" + integrationTestImplementation "org.mockito:mockito-core:5.16.1" + integrationTestImplementation "org.passay:passay:1.6.6" + integrationTestImplementation "org.opensearch:opensearch:${opensearch_version}" + integrationTestImplementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" + integrationTestImplementation "org.opensearch.plugin:aggs-matrix-stats-client:${opensearch_version}" + integrationTestImplementation "org.opensearch.plugin:parent-join-client:${opensearch_version}" + integrationTestImplementation 'com.password4j:password4j:1.8.2' + integrationTestImplementation "com.google.guava:guava:${guava_version}" + integrationTestImplementation "org.apache.commons:commons-lang3:${versions.commonslang}" + integrationTestImplementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}" + integrationTestImplementation 'org.greenrobot:eventbus-java:3.3.1' + integrationTestImplementation('com.flipkart.zjsonpatch:zjsonpatch:0.4.16'){ + exclude(group:'com.fasterxml.jackson.core') + } + integrationTestImplementation 'org.slf4j:slf4j-api:2.0.12' + integrationTestImplementation 'com.selectivem.collections:special-collections-complete:1.4.0' + integrationTestImplementation "org.opensearch.plugin:lang-painless:${opensearch_version}" + integrationTestImplementation project(path:":opensearch-resource-sharing-spi", configuration: 'shadow') + } +} + //create source set 'integrationTest' //add classes from the main source set to the compilation and runtime classpaths of the integrationTest sourceSets { @@ -575,6 +640,7 @@ tasks.integrationTest.finalizedBy(jacocoTestReport) // report is always generate check.dependsOn integrationTest dependencies { + implementation project(path:":opensearch-resource-sharing-spi", configuration: 'shadow') implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" implementation "org.apache.httpcomponents.client5:httpclient5-cache:${versions.httpclient5}" @@ -730,35 +796,11 @@ dependencies { compileOnly "org.opensearch:opensearch:${opensearch_version}" - //integration test framework: - integrationTestImplementation('com.carrotsearch.randomizedtesting:randomizedtesting-runner:2.8.2') { - exclude(group: 'junit', module: 'junit') - } - integrationTestImplementation 'junit:junit:4.13.2' - integrationTestImplementation "org.opensearch.plugin:reindex-client:${opensearch_version}" - integrationTestImplementation "org.opensearch.plugin:percolator-client:${opensearch_version}" - integrationTestImplementation 'commons-io:commons-io:2.18.0' - integrationTestImplementation "org.apache.logging.log4j:log4j-core:${versions.log4j}" - integrationTestImplementation "org.apache.logging.log4j:log4j-jul:${versions.log4j}" - integrationTestImplementation 'org.hamcrest:hamcrest:2.2' - integrationTestImplementation "org.bouncycastle:bcpkix-jdk18on:${versions.bouncycastle}" - integrationTestImplementation "org.bouncycastle:bcutil-jdk18on:${versions.bouncycastle}" - integrationTestImplementation('org.awaitility:awaitility:4.3.0') { - exclude(group: 'org.hamcrest', module: 'hamcrest') - } - integrationTestImplementation 'com.unboundid:unboundid-ldapsdk:4.0.14' - integrationTestImplementation "org.opensearch.plugin:mapper-size:${opensearch_version}" - integrationTestImplementation "org.apache.httpcomponents:httpclient-cache:4.5.14" - integrationTestImplementation "org.apache.httpcomponents:httpclient:4.5.14" - integrationTestImplementation "org.apache.httpcomponents:fluent-hc:4.5.14" - integrationTestImplementation "org.apache.httpcomponents:httpcore:4.4.16" - integrationTestImplementation "org.apache.httpcomponents:httpasyncclient:4.1.5" - integrationTestImplementation "org.mockito:mockito-core:5.16.1" - //spotless implementation('com.google.googlejavaformat:google-java-format:1.25.2') { exclude group: 'com.google.guava' } + } jar { diff --git a/scripts/build.sh b/scripts/build.sh index 4b2893f304..c4476731f5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -77,6 +77,10 @@ echo "COPY ${distributions}/*.zip" mkdir -p $OUTPUT/plugins cp ${distributions}/*.zip ./$OUTPUT/plugins +# Publish jars +./gradlew :opensearch-resource-sharing-spi:publishToMavenLocal -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER +./gradlew publishAllPublicationsToStagingRepository -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER + ./gradlew publishPluginZipPublicationToZipStagingRepository -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER mkdir -p $OUTPUT/maven/org/opensearch cp -r ./build/local-staging-repo/org/opensearch/. $OUTPUT/maven/org/opensearch diff --git a/settings.gradle b/settings.gradle index 1c3e7ff5aa..193587dee7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,3 +5,6 @@ */ rootProject.name = 'opensearch-security' + +include "spi" +project(":spi").name = "opensearch-resource-sharing-spi" diff --git a/spi/README.md b/spi/README.md new file mode 100644 index 0000000000..2d4d13f989 --- /dev/null +++ b/spi/README.md @@ -0,0 +1,167 @@ +# **Resource Sharing and Access Control SPI** + +This **Service Provider Interface (SPI)** provides the necessary **interfaces and mechanisms** to implement **Resource Sharing and Access Control** in OpenSearch. + +--- + +## **Usage** + +A plugin that **defines a resource** and aims to implement **access control** over that resource must **extend** the `ResourceSharingExtension` class to register itself as a **Resource Plugin**. + +### **Example: Implementing a Resource Plugin** +```java +public class SampleResourcePlugin extends Plugin implements SystemIndexPlugin, ResourceSharingExtension { + + // Override required methods + + @Override + public Collection getSystemIndexDescriptors(Settings settings) { + final SystemIndexDescriptor systemIndexDescriptor = + new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Sample index with resources"); + return Collections.singletonList(systemIndexDescriptor); + } + + @Override + public String getResourceType() { + return SampleResource.class.getCanonicalName(); + } + + @Override + public String getResourceIndex() { + return RESOURCE_INDEX_NAME; + } + + @Override + public ResourceParser getResourceParser() { + return new SampleResourceParser(); + } +} +``` + +--- + +## **Checklist for Implementing a Resource Plugin** + +To properly integrate with the **Resource Sharing and Access Control SPI**, follow these steps: + +### **1. Add Required Dependencies** +Include **`opensearch-security-client`** and **`opensearch-resource-sharing-spi`** in your **`build.gradle`** file. +Example: +```gradle +dependencies { + implementation 'org.opensearch:opensearch-security-client:VERSION' + implementation 'org.opensearch:opensearch-resource-sharing-spi:VERSION' +} +``` + +--- + +### **2. Register the Plugin Using the Java SPI Mechanism** +- Navigate to your plugin's `src/main/resources` folder. +- Locate or create the `META-INF/services` directory. +- Inside `META-INF/services`, create a file named: + ``` + org.opensearch.security.spi.resources.ResourceSharingExtension + ``` +- Edit the file and add a **single line** containing the **fully qualified class name** of your plugin implementation. + Example: + ``` + org.opensearch.sample.SampleResourcePlugin + ``` + > This step ensures that OpenSearch **dynamically loads your plugin** as a resource-sharing extension. + +--- + +### **3. Declare a Resource Class** +Each plugin must define a **resource class** that implements the `Resource` interface. +Example: +```java +public class SampleResource implements Resource { + private String id; + private String owner; + + // Constructor, getters, setters, etc. + + @Override + public String getResourceId() { + return id; + } +} +``` + +--- + +### **4. Implement a Resource Parser** +A **`ResourceParser`** is required to convert **resource data** from OpenSearch indices. +Example: +```java +public class SampleResourceParser implements ResourceParser { + @Override + public SampleResource parseXContent(XContentParser parser) throws IOException { + return SampleResource.fromXContent(parser); + } +} +``` + +--- + +### **5. Implement the `ResourceSharingExtension` Interface** +Ensure that your **plugin declaration class** implements `ResourceSharingExtension` and provides **all required methods**. + +**Important:** Mark the resource **index as a system index** to enforce security protections. + +--- + +### **6. Create a Client Accessor** +A **singleton accessor** should be created to manage the `ResourceSharingNodeClient`. +Example: +```java +public class ResourceSharingClientAccessor { + private static ResourceSharingNodeClient INSTANCE; + + private ResourceSharingClientAccessor() {} + + public static ResourceSharingNodeClient getResourceSharingClient(NodeClient nodeClient, Settings settings) { + if (INSTANCE == null) { + INSTANCE = new ResourceSharingNodeClient(nodeClient, settings); + } + return INSTANCE; + } +} +``` + +--- + +### **7. Utilize `ResourceSharingNodeClient` for Access Control** +Use the **client API methods** to manage resource sharing. + +#### **Example: Verifying Resource Access** +```java +Set scopes = Set.of("READ_ONLY"); +resourceSharingClient.verifyResourceAccess( + "resource-123", + "resource_index", + scopes, + ActionListener.wrap(isAuthorized -> { + if (isAuthorized) { + System.out.println("User has access to the resource."); + } else { + System.out.println("Access denied."); + } + }, e -> { + System.err.println("Failed to verify access: " + e.getMessage()); + }) +); +``` + +--- + +## **License** +This project is licensed under the **Apache 2.0 License**. + +--- + +## **Copyright** +© OpenSearch Contributors. + +--- diff --git a/spi/build.gradle b/spi/build.gradle new file mode 100644 index 0000000000..b8f33319b3 --- /dev/null +++ b/spi/build.gradle @@ -0,0 +1,86 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id 'java' + id 'maven-publish' + id 'io.github.goooler.shadow' version "8.1.7" +} + +ext { + opensearch_version = System.getProperty("opensearch.version", "3.0.0-alpha1-SNAPSHOT") +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } +} + +dependencies { + compileOnly "org.opensearch:opensearch:${opensearch_version}" +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +task sourcesJar(type: Jar) { + archiveClassifier.set 'sources' + from sourceSets.main.allJava +} + +task javadocJar(type: Jar) { + archiveClassifier.set 'javadoc' + from tasks.javadoc +} + +publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifact sourcesJar + artifact javadocJar + pom { + name.set("OpenSearch Resource Sharing SPI") + packaging = "jar" + description.set("OpenSearch Security Resource Sharing") + url.set("https://github.com/opensearch-project/security") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + scm { + connection.set("scm:git@github.com:opensearch-project/security.git") + developerConnection.set("scm:git@github.com:opensearch-project/security.git") + url.set("https://github.com/opensearch-project/security.git") + } + developers { + developer { + name.set("OpenSearch Contributors") + url.set("https://github.com/opensearch-project") + } + } + } + } + } + repositories { + maven { + name = "Snapshots" + url = "https://aws.oss.sonatype.org/content/repositories/snapshots" + credentials { + username "$System.env.SONATYPE_USERNAME" + password "$System.env.SONATYPE_PASSWORD" + } + } + maven { + name = 'staging' + url = "${rootProject.buildDir}/local-staging-repo" + } + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/Resource.java b/spi/src/main/java/org/opensearch/security/spi/resources/Resource.java new file mode 100644 index 0000000000..72e0b7b5d1 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/Resource.java @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.xcontent.ToXContentFragment; + +/** + * Marker interface for all resources + * + * @opensearch.experimental + */ +public interface Resource extends NamedWriteable, ToXContentFragment { + /** + * Abstract method to get the resource name. + * Must be implemented by plugins defining resources. + * + * @return resource name + */ + String getResourceName(); +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/ResourceAccessScope.java b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceAccessScope.java new file mode 100644 index 0000000000..c3b54a8c23 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceAccessScope.java @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import java.util.Arrays; + +/** + * This interface defines the two basic access scopes for resource-access. Plugins can decide whether to use these. + * Each plugin must implement their own scopes and manage them. + * These access scopes will then be used to verify the type of access being requested. + * + * @opensearch.experimental + */ +public interface ResourceAccessScope> { + String RESTRICTED = "restricted"; + String PUBLIC = "public"; + + static & ResourceAccessScope> E fromValue(Class enumClass, String value) { + for (E enumConstant : enumClass.getEnumConstants()) { + if (enumConstant.value().equalsIgnoreCase(value)) { + return enumConstant; + } + } + throw new IllegalArgumentException("Unknown value: " + value); + } + + String value(); + + static & ResourceAccessScope> String[] values(Class enumClass) { + return Arrays.stream(enumClass.getEnumConstants()).map(ResourceAccessScope::value).toArray(String[]::new); + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/ResourceParser.java b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceParser.java new file mode 100644 index 0000000000..b02269322e --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceParser.java @@ -0,0 +1,29 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import java.io.IOException; + +import org.opensearch.core.xcontent.XContentParser; + +/** + * Interface for parsing resources from XContentParser + * @param the type of resource to be parsed + * + * @opensearch.experimental + */ +public interface ResourceParser { + /** + * Parse source bytes supplied by the parser to a desired Resource type + * @param parser to parser bytes-ref json input + * @return the parsed object of Resource type + * @throws IOException if something went wrong while parsing + */ + T parseXContent(XContentParser parser) throws IOException; +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/ResourceSharingExtension.java b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceSharingExtension.java new file mode 100644 index 0000000000..bbfc802d82 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/ResourceSharingExtension.java @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +/** + * This interface should be implemented by all the plugins that define one or more resources and need access control over those resources. + * + * @opensearch.experimental + */ +public interface ResourceSharingExtension { + + /** + * Type of the resource + * @return a string containing the type of the resource. A qualified class name can be supplied here. + */ + String getResourceType(); + + /** + * The index where resource is stored + * @return the name of the parent index where resource is stored + */ + String getResourceIndex(); + + /** + * The parser for the resource, which will be used by security plugin to parse the resource + * @return the parser for the resource + */ + ResourceParser getResourceParser(); +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/exceptions/ResourceSharingException.java b/spi/src/main/java/org/opensearch/security/spi/resources/exceptions/ResourceSharingException.java new file mode 100644 index 0000000000..560669112b --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/exceptions/ResourceSharingException.java @@ -0,0 +1,60 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.spi.resources.exceptions; + +import java.io.IOException; + +import org.opensearch.OpenSearchException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.rest.RestStatus; + +/** + * This class represents an exception that occurs during resource sharing operations. + * It extends the OpenSearchException class. + * + * @opensearch.experimental + */ +public class ResourceSharingException extends OpenSearchException { + public ResourceSharingException(Throwable cause) { + super(cause); + } + + public ResourceSharingException(String msg, Object... args) { + super(msg, args); + } + + public ResourceSharingException(String msg, Throwable cause, Object... args) { + super(msg, cause, args); + } + + public ResourceSharingException(StreamInput in) throws IOException { + super(in); + } + + @Override + public RestStatus status() { + String message = getMessage(); + if (message.contains("not authorized")) { + return RestStatus.FORBIDDEN; + } else if (message.startsWith("No authenticated")) { + return RestStatus.UNAUTHORIZED; + } else if (message.contains("not found")) { + return RestStatus.NOT_FOUND; + } else if (message.contains("not a system index")) { + return RestStatus.BAD_REQUEST; + } else if (message.contains("is disabled")) { + return RestStatus.NOT_IMPLEMENTED; + } + + return RestStatus.INTERNAL_SERVER_ERROR; + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/package-info.java b/spi/src/main/java/org/opensearch/security/spi/resources/package-info.java new file mode 100644 index 0000000000..f2e210a5e5 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/package-info.java @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +/** + * This package defines classes required to implement resource access control in OpenSearch. + * This package will be added as a dependency by all OpenSearch plugins that require resource access control. + * + * @opensearch.experimental + */ +package org.opensearch.security.spi.resources; diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/CreatedBy.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/CreatedBy.java new file mode 100644 index 0000000000..50bdd1aea7 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/CreatedBy.java @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +import java.io.IOException; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentFragment; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +/** + * This class is used to store information about the creator of a resource. + * + * @opensearch.experimental + */ +public class CreatedBy implements ToXContentFragment, NamedWriteable { + + private final Creator creatorType; + private final String creator; + + public CreatedBy(Creator creatorType, String creator) { + this.creatorType = creatorType; + this.creator = creator; + } + + public CreatedBy(StreamInput in) throws IOException { + this.creatorType = in.readEnum(Creator.class); + this.creator = in.readString(); + } + + public String getCreator() { + return creator; + } + + public Creator getCreatorType() { + return creatorType; + } + + @Override + public String toString() { + return "CreatedBy {" + this.creatorType.getName() + "='" + this.creator + '\'' + '}'; + } + + @Override + public String getWriteableName() { + return "created_by"; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeEnum(Creator.valueOf(creatorType.name())); + out.writeString(creator); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return builder.startObject().field(creatorType.getName(), creator).endObject(); + } + + public static CreatedBy fromXContent(XContentParser parser) throws IOException { + String creator = null; + Creator creatorType = null; + XContentParser.Token token; + + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + creatorType = Creator.fromName(parser.currentName()); + } else if (token == XContentParser.Token.VALUE_STRING) { + creator = parser.text(); + } + } + + if (creator == null) { + throw new IllegalArgumentException(creatorType + " is required"); + } + + return new CreatedBy(creatorType, creator); + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Creator.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Creator.java new file mode 100644 index 0000000000..75e2415b93 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Creator.java @@ -0,0 +1,37 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +/** + * This enum is used to store information about the creator of a resource. + * + * @opensearch.experimental + */ +public enum Creator { + USER("user"); + + private final String name; + + Creator(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Creator fromName(String name) { + for (Creator creator : values()) { + if (creator.name.equalsIgnoreCase(name)) { // Case-insensitive comparison + return creator; + } + } + throw new IllegalArgumentException("No enum constant for name: " + name); + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Recipient.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Recipient.java new file mode 100644 index 0000000000..77215071de --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/Recipient.java @@ -0,0 +1,31 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +/** + * Enum representing the recipients of a shared resource. + * It includes USERS, ROLES, and BACKEND_ROLES. + * + * @opensearch.experimental + */ +public enum Recipient { + USERS("users"), + ROLES("roles"), + BACKEND_ROLES("backend_roles"); + + private final String name; + + Recipient(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientType.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientType.java new file mode 100644 index 0000000000..d3b916abc2 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientType.java @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +/** + * This class determines a type of recipient a resource can be shared with. + * An example type would be a user or a role. + * This class is used to determine the type of recipient a resource can be shared with. + * + * @opensearch.experimental + */ +public record RecipientType(String type) { + + @Override + public String toString() { + return type; + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientTypeRegistry.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientTypeRegistry.java new file mode 100644 index 0000000000..a1bdb89089 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/RecipientTypeRegistry.java @@ -0,0 +1,39 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +import java.util.HashMap; +import java.util.Map; + +/** + * This class determines a collection of recipient types a resource can be shared with. + * Allows addition of other recipient types in the future. + * + * @opensearch.experimental + */ +public final class RecipientTypeRegistry { + // TODO: Check what size should this be. A cap should be added to avoid infinite addition of objects + private static final Integer REGISTRY_MAX_SIZE = 20; + private static final Map REGISTRY = new HashMap<>(10); + + public static void registerRecipientType(String key, RecipientType recipientType) { + if (REGISTRY.size() == REGISTRY_MAX_SIZE) { + throw new IllegalArgumentException("RecipientTypeRegistry is full. Cannot register more recipient types."); + } + REGISTRY.put(key, recipientType); + } + + public static RecipientType fromValue(String value) { + RecipientType type = REGISTRY.get(value); + if (type == null) { + throw new IllegalArgumentException("Unknown RecipientType: " + value + ". Must be 1 of these: " + REGISTRY.values()); + } + return type; + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ResourceSharing.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ResourceSharing.java new file mode 100644 index 0000000000..1690213872 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ResourceSharing.java @@ -0,0 +1,202 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +import java.io.IOException; +import java.util.Objects; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentFragment; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +/** + * Represents a resource sharing configuration that manages access control for OpenSearch resources. + * This class holds information about shared resources including their source, creator, and sharing permissions. + * The class maintains information about: + *
    + *
  • The source index where the resource is defined
  • + *
  • The unique identifier of the resource
  • + *
  • The creator's information
  • + *
  • The sharing permissions and recipients
  • + *
+ * + * @opensearch.experimental + * @see org.opensearch.security.spi.resources.sharing.CreatedBy + * @see org.opensearch.security.spi.resources.sharing.ShareWith + */ +public class ResourceSharing implements ToXContentFragment, NamedWriteable { + + /** + * The index where the resource is defined + */ + private String sourceIdx; + + /** + * The unique identifier of the resource + */ + private String resourceId; + + /** + * Information about who created the resource + */ + private CreatedBy createdBy; + + /** + * Information about with whom the resource is shared with + */ + private ShareWith shareWith; + + public ResourceSharing(String sourceIdx, String resourceId, CreatedBy createdBy, ShareWith shareWith) { + this.sourceIdx = sourceIdx; + this.resourceId = resourceId; + this.createdBy = createdBy; + this.shareWith = shareWith; + } + + public String getSourceIdx() { + return sourceIdx; + } + + public void setSourceIdx(String sourceIdx) { + this.sourceIdx = sourceIdx; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public CreatedBy getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(CreatedBy createdBy) { + this.createdBy = createdBy; + } + + public ShareWith getShareWith() { + return shareWith; + } + + public void setShareWith(ShareWith shareWith) { + this.shareWith = shareWith; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ResourceSharing resourceSharing = (ResourceSharing) o; + return Objects.equals(getSourceIdx(), resourceSharing.getSourceIdx()) + && Objects.equals(getResourceId(), resourceSharing.getResourceId()) + && Objects.equals(getCreatedBy(), resourceSharing.getCreatedBy()) + && Objects.equals(getShareWith(), resourceSharing.getShareWith()); + } + + @Override + public int hashCode() { + return Objects.hash(getSourceIdx(), getResourceId(), getCreatedBy(), getShareWith()); + } + + @Override + public String toString() { + return "Resource {" + + "sourceIdx='" + + sourceIdx + + '\'' + + ", resourceId='" + + resourceId + + '\'' + + ", createdBy=" + + createdBy + + ", sharedWith=" + + shareWith + + '}'; + } + + @Override + public String getWriteableName() { + return "resource_sharing"; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(sourceIdx); + out.writeString(resourceId); + createdBy.writeTo(out); + if (shareWith != null) { + out.writeBoolean(true); + shareWith.writeTo(out); + } else { + out.writeBoolean(false); + } + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject().field("source_idx", sourceIdx).field("resource_id", resourceId).field("created_by"); + createdBy.toXContent(builder, params); + if (shareWith != null && !shareWith.getSharedWithScopes().isEmpty()) { + builder.field("share_with"); + shareWith.toXContent(builder, params); + } + return builder.endObject(); + } + + public static ResourceSharing fromXContent(XContentParser parser) throws IOException { + String sourceIdx = null; + String resourceId = null; + CreatedBy createdBy = null; + ShareWith shareWith = null; + + String currentFieldName = null; + XContentParser.Token token; + + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else { + switch (Objects.requireNonNull(currentFieldName)) { + case "source_idx": + sourceIdx = parser.text(); + break; + case "resource_id": + resourceId = parser.text(); + break; + case "created_by": + createdBy = CreatedBy.fromXContent(parser); + break; + case "share_with": + shareWith = ShareWith.fromXContent(parser); + break; + default: + parser.skipChildren(); + break; + } + } + } + + validateRequiredField("source_idx", sourceIdx); + validateRequiredField("resource_id", resourceId); + validateRequiredField("created_by", createdBy); + + return new ResourceSharing(sourceIdx, resourceId, createdBy, shareWith); + } + + private static void validateRequiredField(String field, T value) { + if (value == null) { + throw new IllegalArgumentException(field + " is required"); + } + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ShareWith.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ShareWith.java new file mode 100644 index 0000000000..267bb7ece0 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/ShareWith.java @@ -0,0 +1,103 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentFragment; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +/** + * This class contains information about whom a resource is shared with and at what scope. + * Example: + * "share_with": { + * "read_only": { + * "users": [], + * "roles": [], + * "backend_roles": [] + * }, + * "read_write": { + * "users": [], + * "roles": [], + * "backend_roles": [] + * } + * } + * + * @opensearch.experimental + */ +public class ShareWith implements ToXContentFragment, NamedWriteable { + + /** + * A set of objects representing the scopes and their associated users, roles, and backend roles. + */ + private final Set sharedWithScopes; + + public ShareWith(Set sharedWithScopes) { + this.sharedWithScopes = sharedWithScopes; + } + + public ShareWith(StreamInput in) throws IOException { + this.sharedWithScopes = in.readSet(SharedWithScope::new); + } + + public Set getSharedWithScopes() { + return sharedWithScopes; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + + for (SharedWithScope scope : sharedWithScopes) { + scope.toXContent(builder, params); + } + + return builder.endObject(); + } + + public static ShareWith fromXContent(XContentParser parser) throws IOException { + Set sharedWithScopes = new HashSet<>(); + + if (parser.currentToken() != XContentParser.Token.START_OBJECT) { + parser.nextToken(); + } + + XContentParser.Token token; + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + // Each field in the object represents a SharedWithScope + if (token == XContentParser.Token.FIELD_NAME) { + SharedWithScope scope = SharedWithScope.fromXContent(parser); + sharedWithScopes.add(scope); + } + } + + return new ShareWith(sharedWithScopes); + } + + @Override + public String getWriteableName() { + return "share_with"; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeCollection(sharedWithScopes); + } + + @Override + public String toString() { + return "ShareWith " + sharedWithScopes; + } +} diff --git a/spi/src/main/java/org/opensearch/security/spi/resources/sharing/SharedWithScope.java b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/SharedWithScope.java new file mode 100644 index 0000000000..1dfca103a3 --- /dev/null +++ b/spi/src/main/java/org/opensearch/security/spi/resources/sharing/SharedWithScope.java @@ -0,0 +1,169 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources.sharing; + +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentFragment; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; + +/** + * This class represents the scope at which a resource is shared with for a particular scope. + * Example: + * "read_only": { + * "users": [], + * "roles": [], + * "backend_roles": [] + * } + * where "users", "roles" and "backend_roles" are the recipient entities + * + * @opensearch.experimental + */ +public class SharedWithScope implements ToXContentFragment, NamedWriteable { + + private final String scope; + + private final ScopeRecipients scopeRecipients; + + public SharedWithScope(String scope, ScopeRecipients scopeRecipients) { + this.scope = scope; + this.scopeRecipients = scopeRecipients; + } + + public SharedWithScope(StreamInput in) throws IOException { + this.scope = in.readString(); + this.scopeRecipients = new ScopeRecipients(in); + } + + public String getScope() { + return scope; + } + + public ScopeRecipients getSharedWithPerScope() { + return scopeRecipients; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.field(scope); + builder.startObject(); + + scopeRecipients.toXContent(builder, params); + + return builder.endObject(); + } + + public static SharedWithScope fromXContent(XContentParser parser) throws IOException { + String scope = parser.currentName(); + + parser.nextToken(); + + ScopeRecipients scopeRecipients = ScopeRecipients.fromXContent(parser); + + return new SharedWithScope(scope, scopeRecipients); + } + + @Override + public String toString() { + return "{" + scope + ": " + scopeRecipients + '}'; + } + + @Override + public String getWriteableName() { + return "shared_with_scope"; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(scope); + out.writeNamedWriteable(scopeRecipients); + } + + /** + * This class represents the entities with whom a resource is shared with for a given scope. + * + * @opensearch.experimental + */ + public static class ScopeRecipients implements ToXContentFragment, NamedWriteable { + + private final Map> recipients; + + public ScopeRecipients(Map> recipients) { + if (recipients == null) { + throw new IllegalArgumentException("Recipients map cannot be null"); + } + this.recipients = recipients; + } + + public ScopeRecipients(StreamInput in) throws IOException { + this.recipients = in.readMap( + key -> RecipientTypeRegistry.fromValue(key.readString()), + input -> input.readSet(StreamInput::readString) + ); + } + + public Map> getRecipients() { + return recipients; + } + + @Override + public String getWriteableName() { + return "scope_recipients"; + } + + public static ScopeRecipients fromXContent(XContentParser parser) throws IOException { + Map> recipients = new HashMap<>(); + + XContentParser.Token token; + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + String fieldName = parser.currentName(); + RecipientType recipientType = RecipientTypeRegistry.fromValue(fieldName); + + parser.nextToken(); + Set values = new HashSet<>(); + while (parser.nextToken() != XContentParser.Token.END_ARRAY) { + values.add(parser.text()); + } + recipients.put(recipientType, values); + } + } + + return new ScopeRecipients(recipients); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeMap( + recipients, + (streamOutput, recipientType) -> streamOutput.writeString(recipientType.type()), + (streamOutput, strings) -> streamOutput.writeCollection(strings, StreamOutput::writeString) + ); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + if (recipients.isEmpty()) { + return builder; + } + for (Map.Entry> entry : recipients.entrySet()) { + builder.array(entry.getKey().type(), entry.getValue().toArray()); + } + return builder; + } + } +} diff --git a/spi/src/test/java/org/opensearch/security/spi/resources/CreatedByTests.java b/spi/src/test/java/org/opensearch/security/spi/resources/CreatedByTests.java new file mode 100644 index 0000000000..7d6eb5c61a --- /dev/null +++ b/spi/src/test/java/org/opensearch/security/spi/resources/CreatedByTests.java @@ -0,0 +1,320 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import java.io.IOException; + +import org.hamcrest.MatcherAssert; +import org.junit.Test; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.common.xcontent.json.JsonXContent; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.security.spi.resources.sharing.CreatedBy; +import org.opensearch.security.spi.resources.sharing.Creator; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Test class for CreatedBy class + * + * @opensearch.experimental + */ +public class CreatedByTests { + + private static final Creator CREATOR_TYPE = Creator.USER; + + @Test + public void testCreatedByConstructorWithValidUser() { + String expectedUser = "testUser"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser); + + MatcherAssert.assertThat(expectedUser, is(equalTo(createdBy.getCreator()))); + } + + @Test + public void testCreatedByFromStreamInput() throws IOException { + String expectedUser = "testUser"; + + try (BytesStreamOutput out = new BytesStreamOutput()) { + out.writeEnum(Creator.valueOf(CREATOR_TYPE.name())); + out.writeString(expectedUser); + + StreamInput in = out.bytes().streamInput(); + + CreatedBy createdBy = new CreatedBy(in); + + MatcherAssert.assertThat(expectedUser, is(equalTo(createdBy.getCreator()))); + } + } + + @Test + public void testCreatedByWithEmptyStreamInput() throws IOException { + + try (StreamInput mockStreamInput = mock(StreamInput.class)) { + when(mockStreamInput.readString()).thenThrow(new IOException("EOF")); + + assertThrows(IOException.class, () -> new CreatedBy(mockStreamInput)); + } + } + + @Test + public void testCreatedByWithEmptyUser() { + + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, ""); + MatcherAssert.assertThat("", equalTo(createdBy.getCreator())); + } + + @Test + public void testCreatedByWithIOException() throws IOException { + + try (StreamInput mockStreamInput = mock(StreamInput.class)) { + when(mockStreamInput.readString()).thenThrow(new IOException("Test IOException")); + + assertThrows(IOException.class, () -> new CreatedBy(mockStreamInput)); + } + } + + @Test + public void testCreatedByWithLongUsername() { + String longUsername = "a".repeat(10000); + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUsername); + MatcherAssert.assertThat(longUsername, equalTo(createdBy.getCreator())); + } + + @Test + public void testCreatedByWithUnicodeCharacters() { + String unicodeUsername = "用户こんにちは"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, unicodeUsername); + MatcherAssert.assertThat(unicodeUsername, equalTo(createdBy.getCreator())); + } + + @Test + public void testFromXContentThrowsExceptionWhenUserFieldIsMissing() throws IOException { + String emptyJson = "{}"; + IllegalArgumentException exception; + try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) { + + exception = assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser)); + } + + MatcherAssert.assertThat("null is required", equalTo(exception.getMessage())); + } + + @Test + public void testFromXContentWithEmptyInput() throws IOException { + String emptyJson = "{}"; + try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) { + + assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser)); + } + } + + @Test + public void testFromXContentWithExtraFields() throws IOException { + String jsonWithExtraFields = "{\"user\": \"testUser\", \"extraField\": \"value\"}"; + XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithExtraFields); + + assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser)); + } + + @Test + public void testFromXContentWithIncorrectFieldType() throws IOException { + String jsonWithIncorrectType = "{\"user\": 12345}"; + try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithIncorrectType)) { + + assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser)); + } + } + + @Test + public void testFromXContentWithEmptyUser() throws IOException { + String emptyJson = "{\"" + CREATOR_TYPE + "\": \"\" }"; + CreatedBy createdBy; + try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) { + parser.nextToken(); + + createdBy = CreatedBy.fromXContent(parser); + } + + MatcherAssert.assertThat(CREATOR_TYPE, equalTo(createdBy.getCreatorType())); + MatcherAssert.assertThat("", equalTo(createdBy.getCreator())); + } + + @Test + public void testFromXContentWithNullUserValue() throws IOException { + String jsonWithNullUser = "{\"user\": null}"; + try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithNullUser)) { + + assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser)); + } + } + + @Test + public void testFromXContentWithValidUser() throws IOException { + String json = "{\"user\":\"testUser\"}"; + XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, json); + + CreatedBy createdBy = CreatedBy.fromXContent(parser); + + MatcherAssert.assertThat(createdBy, notNullValue()); + MatcherAssert.assertThat("testUser", equalTo(createdBy.getCreator())); + } + + @Test + public void testGetCreatorReturnsCorrectValue() { + String expectedUser = "testUser"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser); + + String actualUser = createdBy.getCreator(); + + MatcherAssert.assertThat(expectedUser, equalTo(actualUser)); + } + + @Test + public void testGetCreatorWithNullString() { + + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, null); + MatcherAssert.assertThat(createdBy.getCreator(), nullValue()); + } + + @Test + public void testGetWriteableNameReturnsCorrectString() { + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "testUser"); + MatcherAssert.assertThat("created_by", equalTo(createdBy.getWriteableName())); + } + + @Test + public void testToStringWithEmptyUser() { + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, ""); + String result = createdBy.toString(); + MatcherAssert.assertThat("CreatedBy {user=''}", equalTo(result)); + } + + @Test + public void testToStringWithNullUser() { + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, (String) null); + String result = createdBy.toString(); + MatcherAssert.assertThat("CreatedBy {user='null'}", equalTo(result)); + } + + @Test + public void testToStringWithLongUserName() { + + String longUserName = "a".repeat(1000); + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUserName); + String result = createdBy.toString(); + MatcherAssert.assertThat(result.startsWith("CreatedBy {user='"), is(true)); + MatcherAssert.assertThat(result.endsWith("'}"), is(true)); + MatcherAssert.assertThat(1019, equalTo(result.length())); + } + + @Test + public void testToXContentWithEmptyUser() throws IOException { + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, ""); + XContentBuilder builder = JsonXContent.contentBuilder(); + + createdBy.toXContent(builder, null); + String result = builder.toString(); + MatcherAssert.assertThat("{\"user\":\"\"}", equalTo(result)); + } + + @Test + public void testWriteToWithExceptionInStreamOutput() throws IOException { + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "user1"); + try (StreamOutput failingOutput = new StreamOutput() { + @Override + public void writeByte(byte b) throws IOException { + throw new IOException("Simulated IO exception"); + } + + @Override + public void writeBytes(byte[] b, int offset, int length) throws IOException { + throw new IOException("Simulated IO exception"); + } + + @Override + public void flush() throws IOException { + + } + + @Override + public void close() throws IOException { + + } + + @Override + public void reset() throws IOException { + + } + }) { + + assertThrows(IOException.class, () -> createdBy.writeTo(failingOutput)); + } + } + + @Test + public void testWriteToWithLongUserName() throws IOException { + String longUserName = "a".repeat(65536); + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUserName); + BytesStreamOutput out = new BytesStreamOutput(); + createdBy.writeTo(out); + MatcherAssert.assertThat(out.size(), greaterThan(65536)); + } + + @Test + public void test_createdByToStringReturnsCorrectFormat() { + String testUser = "testUser"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, testUser); + + String expected = "CreatedBy {user='" + testUser + "'}"; + String actual = createdBy.toString(); + + MatcherAssert.assertThat(expected, equalTo(actual)); + } + + @Test + public void test_toXContent_serializesCorrectly() throws IOException { + String expectedUser = "testUser"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser); + XContentBuilder builder = XContentFactory.jsonBuilder(); + + createdBy.toXContent(builder, null); + + String expectedJson = "{\"user\":\"testUser\"}"; + MatcherAssert.assertThat(expectedJson, equalTo(builder.toString())); + } + + @Test + public void test_writeTo_writesUserCorrectly() throws IOException { + String expectedUser = "testUser"; + CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser); + + BytesStreamOutput out = new BytesStreamOutput(); + createdBy.writeTo(out); + + StreamInput in = out.bytes().streamInput(); + in.readString(); + String actualUser = in.readString(); + + MatcherAssert.assertThat(expectedUser, equalTo(actualUser)); + } + +} diff --git a/spi/src/test/java/org/opensearch/security/spi/resources/RecipientTypeRegistryTests.java b/spi/src/test/java/org/opensearch/security/spi/resources/RecipientTypeRegistryTests.java new file mode 100644 index 0000000000..8b0bfa3297 --- /dev/null +++ b/spi/src/test/java/org/opensearch/security/spi/resources/RecipientTypeRegistryTests.java @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import org.hamcrest.MatcherAssert; +import org.junit.Test; + +import org.opensearch.security.spi.resources.sharing.RecipientType; +import org.opensearch.security.spi.resources.sharing.RecipientTypeRegistry; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThrows; + +/** + * Tests for {@link RecipientTypeRegistry}. + * + * @opensearch.experimental + */ +public class RecipientTypeRegistryTests { + + @Test + public void testFromValue() { + RecipientTypeRegistry.registerRecipientType("ble1", new RecipientType("ble1")); + RecipientTypeRegistry.registerRecipientType("ble2", new RecipientType("ble2")); + + // Valid Value + RecipientType type = RecipientTypeRegistry.fromValue("ble1"); + MatcherAssert.assertThat(type, notNullValue()); + MatcherAssert.assertThat(type.type(), is(equalTo("ble1"))); + + // Invalid Value + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> RecipientTypeRegistry.fromValue("bleble")); + MatcherAssert.assertThat("Unknown RecipientType: bleble. Must be 1 of these: [ble1, ble2]", is(equalTo(exception.getMessage()))); + } +} diff --git a/spi/src/test/java/org/opensearch/security/spi/resources/ShareWithTests.java b/spi/src/test/java/org/opensearch/security/spi/resources/ShareWithTests.java new file mode 100644 index 0000000000..d7ffa0ce5e --- /dev/null +++ b/spi/src/test/java/org/opensearch/security/spi/resources/ShareWithTests.java @@ -0,0 +1,284 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.spi.resources; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.hamcrest.MatcherAssert; +import org.junit.Before; +import org.junit.Test; + +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.common.xcontent.json.JsonXContent; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.security.spi.resources.sharing.RecipientType; +import org.opensearch.security.spi.resources.sharing.RecipientTypeRegistry; +import org.opensearch.security.spi.resources.sharing.ShareWith; +import org.opensearch.security.spi.resources.sharing.SharedWithScope; + +import org.mockito.Mockito; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Test class for ShareWith class + * + * @opensearch.experimental + */ +public class ShareWithTests { + + @Before + public void setupResourceRecipientTypes() { + initializeRecipientTypes(); + } + + @Test + public void testFromXContentWhenCurrentTokenIsNotStartObject() throws IOException { + String json = "{\"read_only\": {\"users\": [\"user1\"], \"roles\": [], \"backend_roles\": []}}"; + XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, json); + + parser.nextToken(); + + ShareWith shareWith = ShareWith.fromXContent(parser); + + MatcherAssert.assertThat(shareWith, notNullValue()); + Set sharedWithScopes = shareWith.getSharedWithScopes(); + MatcherAssert.assertThat(sharedWithScopes, notNullValue()); + MatcherAssert.assertThat(1, equalTo(sharedWithScopes.size())); + + SharedWithScope scope = sharedWithScopes.iterator().next(); + MatcherAssert.assertThat("read_only", equalTo(scope.getScope())); + + SharedWithScope.ScopeRecipients scopeRecipients = scope.getSharedWithPerScope(); + MatcherAssert.assertThat(scopeRecipients, notNullValue()); + Map> recipients = scopeRecipients.getRecipients(); + MatcherAssert.assertThat(recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.USERS.getName())).size(), is(1)); + MatcherAssert.assertThat(recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.USERS.getName())), contains("user1")); + MatcherAssert.assertThat(recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.ROLES.getName())).size(), is(0)); + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.BACKEND_ROLES.getName())).size(), + is(0) + ); + } + + @Test + public void testFromXContentWithEmptyInput() throws IOException { + String emptyJson = "{}"; + XContentParser parser = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, null, emptyJson); + + ShareWith result = ShareWith.fromXContent(parser); + + MatcherAssert.assertThat(result, notNullValue()); + MatcherAssert.assertThat(result.getSharedWithScopes(), is(empty())); + } + + @Test + public void testFromXContentWithStartObject() throws IOException { + XContentParser parser; + try (XContentBuilder builder = XContentFactory.jsonBuilder()) { + builder.startObject() + .startObject(ResourceAccessScope.RESTRICTED) + .array("users", "user1", "user2") + .array("roles", "role1") + .array("backend_roles", "backend_role1") + .endObject() + .startObject(ResourceAccessScope.PUBLIC) + .array("users", "user3") + .array("roles", "role2", "role3") + .array("backend_roles") + .endObject() + .endObject(); + + parser = JsonXContent.jsonXContent.createParser(null, null, builder.toString()); + } + + parser.nextToken(); + + ShareWith shareWith = ShareWith.fromXContent(parser); + + MatcherAssert.assertThat(shareWith, notNullValue()); + Set scopes = shareWith.getSharedWithScopes(); + MatcherAssert.assertThat(scopes.size(), equalTo(2)); + + for (SharedWithScope scope : scopes) { + SharedWithScope.ScopeRecipients perScope = scope.getSharedWithPerScope(); + Map> recipients = perScope.getRecipients(); + if (scope.getScope().equals(ResourceAccessScope.RESTRICTED)) { + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.USERS.getName())).size(), + is(2) + ); + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.ROLES.getName())).size(), + is(1) + ); + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.BACKEND_ROLES.getName())).size(), + is(1) + ); + } else if (scope.getScope().equals(ResourceAccessScope.PUBLIC)) { + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.USERS.getName())).size(), + is(1) + ); + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.ROLES.getName())).size(), + is(2) + ); + MatcherAssert.assertThat( + recipients.get(RecipientTypeRegistry.fromValue(DefaultRecipientType.BACKEND_ROLES.getName())).size(), + is(0) + ); + } + } + } + + @Test + public void testFromXContentWithUnexpectedEndOfInput() throws IOException { + XContentParser mockParser = mock(XContentParser.class); + when(mockParser.currentToken()).thenReturn(XContentParser.Token.START_OBJECT); + when(mockParser.nextToken()).thenReturn(XContentParser.Token.END_OBJECT, (XContentParser.Token) null); + + ShareWith result = ShareWith.fromXContent(mockParser); + + MatcherAssert.assertThat(result, notNullValue()); + MatcherAssert.assertThat(result.getSharedWithScopes(), is(empty())); + } + + @Test + public void testToXContentBuildsCorrectly() throws IOException { + SharedWithScope scope = new SharedWithScope( + "scope1", + new SharedWithScope.ScopeRecipients(Map.of(new RecipientType("users"), Set.of("bleh"))) + ); + + Set scopes = new HashSet<>(); + scopes.add(scope); + + ShareWith shareWith = new ShareWith(scopes); + + XContentBuilder builder = JsonXContent.contentBuilder(); + + shareWith.toXContent(builder, ToXContent.EMPTY_PARAMS); + + String result = builder.toString(); + + String expected = "{\"scope1\":{\"users\":[\"bleh\"]}}"; + + MatcherAssert.assertThat(expected.length(), equalTo(result.length())); + MatcherAssert.assertThat(expected, equalTo(result)); + } + + @Test + public void testWriteToWithEmptySet() throws IOException { + Set emptySet = Collections.emptySet(); + ShareWith shareWith = new ShareWith(emptySet); + StreamOutput mockOutput = Mockito.mock(StreamOutput.class); + + shareWith.writeTo(mockOutput); + + verify(mockOutput).writeCollection(emptySet); + } + + @Test + public void testWriteToWithIOException() throws IOException { + Set set = new HashSet<>(); + set.add(new SharedWithScope("test", new SharedWithScope.ScopeRecipients(Map.of()))); + ShareWith shareWith = new ShareWith(set); + StreamOutput mockOutput = Mockito.mock(StreamOutput.class); + + doThrow(new IOException("Simulated IO exception")).when(mockOutput).writeCollection(set); + + assertThrows(IOException.class, () -> shareWith.writeTo(mockOutput)); + } + + @Test + public void testWriteToWithLargeSet() throws IOException { + Set largeSet = new HashSet<>(); + for (int i = 0; i < 10000; i++) { + largeSet.add(new SharedWithScope("scope" + i, new SharedWithScope.ScopeRecipients(Map.of()))); + } + ShareWith shareWith = new ShareWith(largeSet); + StreamOutput mockOutput = Mockito.mock(StreamOutput.class); + + shareWith.writeTo(mockOutput); + + verify(mockOutput).writeCollection(largeSet); + } + + @Test + public void test_fromXContent_emptyObject() throws IOException { + XContentParser parser; + try (XContentBuilder builder = XContentFactory.jsonBuilder()) { + builder.startObject().endObject(); + parser = XContentType.JSON.xContent().createParser(null, null, builder.toString()); + } + + ShareWith shareWith = ShareWith.fromXContent(parser); + + MatcherAssert.assertThat(shareWith.getSharedWithScopes(), is(empty())); + } + + @Test + public void test_writeSharedWithScopesToStream() throws IOException { + StreamOutput mockStreamOutput = Mockito.mock(StreamOutput.class); + + Set sharedWithScopes = new HashSet<>(); + sharedWithScopes.add(new SharedWithScope(ResourceAccessScope.RESTRICTED, new SharedWithScope.ScopeRecipients(Map.of()))); + sharedWithScopes.add(new SharedWithScope(ResourceAccessScope.PUBLIC, new SharedWithScope.ScopeRecipients(Map.of()))); + + ShareWith shareWith = new ShareWith(sharedWithScopes); + + shareWith.writeTo(mockStreamOutput); + + verify(mockStreamOutput, times(1)).writeCollection(eq(sharedWithScopes)); + } + + private void initializeRecipientTypes() { + RecipientTypeRegistry.registerRecipientType("users", new RecipientType("users")); + RecipientTypeRegistry.registerRecipientType("roles", new RecipientType("roles")); + RecipientTypeRegistry.registerRecipientType("backend_roles", new RecipientType("backend_roles")); + } +} + +enum DefaultRecipientType { + USERS("users"), + ROLES("roles"), + BACKEND_ROLES("backend_roles"); + + private final String name; + + DefaultRecipientType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 0802cb856c..843553d971 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -116,6 +116,7 @@ import org.opensearch.indices.IndicesService; import org.opensearch.indices.SystemIndexDescriptor; import org.opensearch.plugins.ClusterPlugin; +import org.opensearch.plugins.ExtensiblePlugin; import org.opensearch.plugins.ExtensionAwarePlugin; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.MapperPlugin; @@ -236,9 +237,10 @@ public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin implements ClusterPlugin, MapperPlugin, + IdentityPlugin, // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings ExtensionAwarePlugin, - IdentityPlugin + ExtensiblePlugin // CS-ENFORCE-SINGLE { @@ -1194,7 +1196,7 @@ public Collection createComponents( // NOTE: We need to create DefaultInterClusterRequestEvaluator before creating ConfigurationRepository since the latter requires // security index to be accessible which means - // communciation with other nodes is already up. However for the communication to be up, there needs to be trusted nodes_dn. Hence + // communication with other nodes is already up. However for the communication to be up, there needs to be trusted nodes_dn. Hence // the base values from opensearch.yml // is used to first establish trust between same cluster nodes and there after dynamic config is loaded if enabled. if (DEFAULT_INTERCLUSTER_REQUEST_EVALUATOR_CLASS.equals(className)) { @@ -2141,8 +2143,8 @@ public Collection getSystemIndexDescriptors(Settings sett ConfigConstants.SECURITY_CONFIG_INDEX_NAME, ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX ); - final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(indexPattern, "Security index"); - return Collections.singletonList(systemIndexDescriptor); + final SystemIndexDescriptor securityIndexDescriptor = new SystemIndexDescriptor(indexPattern, "Security index"); + return List.of(securityIndexDescriptor); } @Override @@ -2201,6 +2203,13 @@ private void tryAddSecurityProvider() { }); } + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings + @Override + public void loadExtensions(ExtensiblePlugin.ExtensionLoader loader) { + // Resource Sharing extensions will be loaded here + } + // CS-ENFORCE-SINGLE + public static class GuiceHolder implements LifecycleComponent { private static RepositoriesService repositoriesService; diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index 307db9cbcd..633b85cff6 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -43,6 +43,7 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_CONFIG_PREFIX = "_opendistro_security_"; + public static final String SECURITY_SETTINGS_PREFIX = "plugins.security."; public static final String OPENDISTRO_SECURITY_CHANNEL_TYPE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "channel_type"; @@ -131,11 +132,11 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX = ".opendistro_security"; - public static final String SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = "plugins.security.enable_snapshot_restore_privilege"; + public static final String SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = SECURITY_SETTINGS_PREFIX + "enable_snapshot_restore_privilege"; public static final boolean SECURITY_DEFAULT_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = true; - public static final String SECURITY_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = - "plugins.security.check_snapshot_restore_write_privileges"; + public static final String SECURITY_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = SECURITY_SETTINGS_PREFIX + + "check_snapshot_restore_write_privileges"; public static final boolean SECURITY_DEFAULT_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = true; public static final Set SECURITY_SNAPSHOT_RESTORE_NEEDED_WRITE_PRIVILEGES = Collections.unmodifiableSet( new HashSet(Arrays.asList("indices:admin/create", "indices:data/write/index" @@ -143,37 +144,39 @@ public class ConfigConstants { )) ); - public static final String SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = "plugins.security.cert.intercluster_request_evaluator_class"; + public static final String SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX + + "cert.intercluster_request_evaluator_class"; public static final String OPENDISTRO_SECURITY_ACTION_NAME = OPENDISTRO_SECURITY_CONFIG_PREFIX + "action_name"; - public static final String SECURITY_AUTHCZ_ADMIN_DN = "plugins.security.authcz.admin_dn"; - public static final String SECURITY_CONFIG_INDEX_NAME = "plugins.security.config_index_name"; - public static final String SECURITY_AUTHCZ_IMPERSONATION_DN = "plugins.security.authcz.impersonation_dn"; - public static final String SECURITY_AUTHCZ_REST_IMPERSONATION_USERS = "plugins.security.authcz.rest_impersonation_user"; + public static final String SECURITY_AUTHCZ_ADMIN_DN = SECURITY_SETTINGS_PREFIX + "authcz.admin_dn"; + public static final String SECURITY_CONFIG_INDEX_NAME = SECURITY_SETTINGS_PREFIX + "config_index_name"; + public static final String SECURITY_AUTHCZ_IMPERSONATION_DN = SECURITY_SETTINGS_PREFIX + "authcz.impersonation_dn"; + public static final String SECURITY_AUTHCZ_REST_IMPERSONATION_USERS = SECURITY_SETTINGS_PREFIX + "authcz.rest_impersonation_user"; public static final String BCRYPT = "bcrypt"; public static final String PBKDF2 = "pbkdf2"; - public static final String SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS = "plugins.security.password.hashing.bcrypt.rounds"; + public static final String SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.rounds"; public static final int SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS_DEFAULT = 12; - public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR = "plugins.security.password.hashing.bcrypt.minor"; + public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.minor"; public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR_DEFAULT = "Y"; - public static final String SECURITY_PASSWORD_HASHING_ALGORITHM = "plugins.security.password.hashing.algorithm"; + public static final String SECURITY_PASSWORD_HASHING_ALGORITHM = SECURITY_SETTINGS_PREFIX + "password.hashing.algorithm"; public static final String SECURITY_PASSWORD_HASHING_ALGORITHM_DEFAULT = BCRYPT; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS = "plugins.security.password.hashing.pbkdf2.iterations"; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS = SECURITY_SETTINGS_PREFIX + + "password.hashing.pbkdf2.iterations"; public static final int SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS_DEFAULT = 600_000; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH = "plugins.security.password.hashing.pbkdf2.length"; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.length"; public static final int SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH_DEFAULT = 256; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION = "plugins.security.password.hashing.pbkdf2.function"; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.function"; public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION_DEFAULT = Hmac.SHA256.name(); - public static final String SECURITY_AUDIT_TYPE_DEFAULT = "plugins.security.audit.type"; - public static final String SECURITY_AUDIT_CONFIG_DEFAULT = "plugins.security.audit.config"; - public static final String SECURITY_AUDIT_CONFIG_ROUTES = "plugins.security.audit.routes"; - public static final String SECURITY_AUDIT_CONFIG_ENDPOINTS = "plugins.security.audit.endpoints"; - public static final String SECURITY_AUDIT_THREADPOOL_SIZE = "plugins.security.audit.threadpool.size"; - public static final String SECURITY_AUDIT_THREADPOOL_MAX_QUEUE_LEN = "plugins.security.audit.threadpool.max_queue_len"; + public static final String SECURITY_AUDIT_TYPE_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.type"; + public static final String SECURITY_AUDIT_CONFIG_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.config"; + public static final String SECURITY_AUDIT_CONFIG_ROUTES = SECURITY_SETTINGS_PREFIX + "audit.routes"; + public static final String SECURITY_AUDIT_CONFIG_ENDPOINTS = SECURITY_SETTINGS_PREFIX + "audit.endpoints"; + public static final String SECURITY_AUDIT_THREADPOOL_SIZE = SECURITY_SETTINGS_PREFIX + "audit.threadpool.size"; + public static final String SECURITY_AUDIT_THREADPOOL_MAX_QUEUE_LEN = SECURITY_SETTINGS_PREFIX + "audit.threadpool.max_queue_len"; public static final String OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY = "opendistro_security.audit.log_request_body"; public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES = "opendistro_security.audit.resolve_indices"; public static final String OPENDISTRO_SECURITY_AUDIT_ENABLE_REST = "opendistro_security.audit.enable_rest"; @@ -188,13 +191,13 @@ public class ConfigConstants { ); public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS = "opendistro_security.audit.ignore_users"; public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS = "opendistro_security.audit.ignore_requests"; - public static final String SECURITY_AUDIT_IGNORE_HEADERS = "plugins.security.audit.ignore_headers"; + public static final String SECURITY_AUDIT_IGNORE_HEADERS = SECURITY_SETTINGS_PREFIX + "audit.ignore_headers"; public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS = "opendistro_security.audit.resolve_bulk_requests"; public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_VERIFY_HOSTNAMES_DEFAULT = true; public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_ENABLE_SSL_CLIENT_AUTH_DEFAULT = false; public static final String OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS = "opendistro_security.audit.exclude_sensitive_headers"; - public static final String SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX = "plugins.security.audit.config."; + public static final String SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX = SECURITY_SETTINGS_PREFIX + "audit.config."; // Internal Opensearch data_stream public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_NAME = "data_stream.name"; @@ -237,31 +240,31 @@ public class ConfigConstants { public static final String SECURITY_AUDIT_LOG4J_LEVEL = "log4j.level"; // retry - public static final String SECURITY_AUDIT_RETRY_COUNT = "plugins.security.audit.config.retry_count"; - public static final String SECURITY_AUDIT_RETRY_DELAY_MS = "plugins.security.audit.config.retry_delay_ms"; + public static final String SECURITY_AUDIT_RETRY_COUNT = SECURITY_SETTINGS_PREFIX + "audit.config.retry_count"; + public static final String SECURITY_AUDIT_RETRY_DELAY_MS = SECURITY_SETTINGS_PREFIX + "audit.config.retry_delay_ms"; - public static final String SECURITY_KERBEROS_KRB5_FILEPATH = "plugins.security.kerberos.krb5_filepath"; - public static final String SECURITY_KERBEROS_ACCEPTOR_KEYTAB_FILEPATH = "plugins.security.kerberos.acceptor_keytab_filepath"; - public static final String SECURITY_KERBEROS_ACCEPTOR_PRINCIPAL = "plugins.security.kerberos.acceptor_principal"; - public static final String SECURITY_CERT_OID = "plugins.security.cert.oid"; - public static final String SECURITY_CERT_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = - "plugins.security.cert.intercluster_request_evaluator_class"; - public static final String SECURITY_ADVANCED_MODULES_ENABLED = "plugins.security.advanced_modules_enabled"; - public static final String SECURITY_NODES_DN = "plugins.security.nodes_dn"; - public static final String SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED = "plugins.security.nodes_dn_dynamic_config_enabled"; - public static final String SECURITY_DISABLED = "plugins.security.disabled"; + public static final String SECURITY_KERBEROS_KRB5_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.krb5_filepath"; + public static final String SECURITY_KERBEROS_ACCEPTOR_KEYTAB_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_keytab_filepath"; + public static final String SECURITY_KERBEROS_ACCEPTOR_PRINCIPAL = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_principal"; + public static final String SECURITY_CERT_OID = SECURITY_SETTINGS_PREFIX + "cert.oid"; + public static final String SECURITY_CERT_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX + + "cert.intercluster_request_evaluator_class"; + public static final String SECURITY_ADVANCED_MODULES_ENABLED = SECURITY_SETTINGS_PREFIX + "advanced_modules_enabled"; + public static final String SECURITY_NODES_DN = SECURITY_SETTINGS_PREFIX + "nodes_dn"; + public static final String SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED = SECURITY_SETTINGS_PREFIX + "nodes_dn_dynamic_config_enabled"; + public static final String SECURITY_DISABLED = SECURITY_SETTINGS_PREFIX + "disabled"; - public static final String SECURITY_CACHE_TTL_MINUTES = "plugins.security.cache.ttl_minutes"; - public static final String SECURITY_ALLOW_UNSAFE_DEMOCERTIFICATES = "plugins.security.allow_unsafe_democertificates"; - public static final String SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX = "plugins.security.allow_default_init_securityindex"; + public static final String SECURITY_CACHE_TTL_MINUTES = SECURITY_SETTINGS_PREFIX + "cache.ttl_minutes"; + public static final String SECURITY_ALLOW_UNSAFE_DEMOCERTIFICATES = SECURITY_SETTINGS_PREFIX + "allow_unsafe_democertificates"; + public static final String SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX = SECURITY_SETTINGS_PREFIX + "allow_default_init_securityindex"; - public static final String SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE = - "plugins.security.allow_default_init_securityindex.use_cluster_state"; + public static final String SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE = SECURITY_SETTINGS_PREFIX + + "allow_default_init_securityindex.use_cluster_state"; - public static final String SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST = - "plugins.security.background_init_if_securityindex_not_exist"; + public static final String SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST = SECURITY_SETTINGS_PREFIX + + "background_init_if_securityindex_not_exist"; - public static final String SECURITY_ROLES_MAPPING_RESOLUTION = "plugins.security.roles_mapping_resolution"; + public static final String SECURITY_ROLES_MAPPING_RESOLUTION = SECURITY_SETTINGS_PREFIX + "roles_mapping_resolution"; public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_METADATA_ONLY = "opendistro_security.compliance.history.write.metadata_only"; @@ -280,21 +283,22 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED = "opendistro_security.compliance.history.external_config_enabled"; public static final String OPENDISTRO_SECURITY_SOURCE_FIELD_CONTEXT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "source_field_context"; - public static final String SECURITY_COMPLIANCE_DISABLE_ANONYMOUS_AUTHENTICATION = - "plugins.security.compliance.disable_anonymous_authentication"; - public static final String SECURITY_COMPLIANCE_IMMUTABLE_INDICES = "plugins.security.compliance.immutable_indices"; - public static final String SECURITY_COMPLIANCE_SALT = "plugins.security.compliance.salt"; + public static final String SECURITY_COMPLIANCE_DISABLE_ANONYMOUS_AUTHENTICATION = SECURITY_SETTINGS_PREFIX + + "compliance.disable_anonymous_authentication"; + public static final String SECURITY_COMPLIANCE_IMMUTABLE_INDICES = SECURITY_SETTINGS_PREFIX + "compliance.immutable_indices"; + public static final String SECURITY_COMPLIANCE_SALT = SECURITY_SETTINGS_PREFIX + "compliance.salt"; public static final String SECURITY_COMPLIANCE_SALT_DEFAULT = "e1ukloTsQlOgPquJ";// 16 chars public static final String SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED = "opendistro_security.compliance.history.internal_config_enabled"; - public static final String SECURITY_SSL_ONLY = "plugins.security.ssl_only"; + public static final String SECURITY_SSL_ONLY = SECURITY_SETTINGS_PREFIX + "ssl_only"; public static final String SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "plugins.security_config.ssl_dual_mode_enabled"; public static final String SECURITY_SSL_DUAL_MODE_SKIP_SECURITY = OPENDISTRO_SECURITY_CONFIG_PREFIX + "passive_security"; public static final String LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "opendistro_security_config.ssl_dual_mode_enabled"; - public static final String SECURITY_SSL_CERT_RELOAD_ENABLED = "plugins.security.ssl_cert_reload_enabled"; - public static final String SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED = "plugins.security.ssl.certificates_hot_reload.enabled"; - public static final String SECURITY_DISABLE_ENVVAR_REPLACEMENT = "plugins.security.disable_envvar_replacement"; - public static final String SECURITY_DFM_EMPTY_OVERRIDES_ALL = "plugins.security.dfm_empty_overrides_all"; + public static final String SECURITY_SSL_CERT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX + "ssl_cert_reload_enabled"; + public static final String SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX + + "ssl.certificates_hot_reload.enabled"; + public static final String SECURITY_DISABLE_ENVVAR_REPLACEMENT = SECURITY_SETTINGS_PREFIX + "disable_envvar_replacement"; + public static final String SECURITY_DFM_EMPTY_OVERRIDES_ALL = SECURITY_SETTINGS_PREFIX + "dfm_empty_overrides_all"; public enum RolesMappingResolution { MAPPING_ONLY, @@ -302,43 +306,45 @@ public enum RolesMappingResolution { BOTH } - public static final String SECURITY_FILTER_SECURITYINDEX_FROM_ALL_REQUESTS = "plugins.security.filter_securityindex_from_all_requests"; - public static final String SECURITY_DLS_MODE = "plugins.security.dls.mode"; + public static final String SECURITY_FILTER_SECURITYINDEX_FROM_ALL_REQUESTS = SECURITY_SETTINGS_PREFIX + + "filter_securityindex_from_all_requests"; + public static final String SECURITY_DLS_MODE = SECURITY_SETTINGS_PREFIX + "dls.mode"; // REST API - public static final String SECURITY_RESTAPI_ROLES_ENABLED = "plugins.security.restapi.roles_enabled"; - public static final String SECURITY_RESTAPI_ADMIN_ENABLED = "plugins.security.restapi.admin.enabled"; - public static final String SECURITY_RESTAPI_ENDPOINTS_DISABLED = "plugins.security.restapi.endpoints_disabled"; - public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX = "plugins.security.restapi.password_validation_regex"; - public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE = - "plugins.security.restapi.password_validation_error_message"; - public static final String SECURITY_RESTAPI_PASSWORD_MIN_LENGTH = "plugins.security.restapi.password_min_length"; - public static final String SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH = - "plugins.security.restapi.password_score_based_validation_strength"; + public static final String SECURITY_RESTAPI_ROLES_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.roles_enabled"; + public static final String SECURITY_RESTAPI_ADMIN_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.admin.enabled"; + public static final String SECURITY_RESTAPI_ENDPOINTS_DISABLED = SECURITY_SETTINGS_PREFIX + "restapi.endpoints_disabled"; + public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX = SECURITY_SETTINGS_PREFIX + "restapi.password_validation_regex"; + public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE = SECURITY_SETTINGS_PREFIX + + "restapi.password_validation_error_message"; + public static final String SECURITY_RESTAPI_PASSWORD_MIN_LENGTH = SECURITY_SETTINGS_PREFIX + "restapi.password_min_length"; + public static final String SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH = SECURITY_SETTINGS_PREFIX + + "restapi.password_score_based_validation_strength"; // Illegal Opcodes from here on - public static final String SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY = - "plugins.security.unsupported.disable_rest_auth_initially"; - public static final String SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS = - "plugins.security.unsupported.delay_initialization_seconds"; - public static final String SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY = - "plugins.security.unsupported.disable_intertransport_auth_initially"; - public static final String SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY = - "plugins.security.unsupported.passive_intertransport_auth_initially"; - public static final String SECURITY_UNSUPPORTED_RESTORE_SECURITYINDEX_ENABLED = - "plugins.security.unsupported.restore.securityindex.enabled"; - public static final String SECURITY_UNSUPPORTED_INJECT_USER_ENABLED = "plugins.security.unsupported.inject_user.enabled"; - public static final String SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED = "plugins.security.unsupported.inject_user.admin.enabled"; - public static final String SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS = "plugins.security.unsupported.allow_now_in_dls"; - - public static final String SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION = - "plugins.security.unsupported.restapi.allow_securityconfig_modification"; - public static final String SECURITY_UNSUPPORTED_LOAD_STATIC_RESOURCES = "plugins.security.unsupported.load_static_resources"; - public static final String SECURITY_UNSUPPORTED_ACCEPT_INVALID_CONFIG = "plugins.security.unsupported.accept_invalid_config"; - - public static final String SECURITY_PROTECTED_INDICES_ENABLED_KEY = "plugins.security.protected_indices.enabled"; + public static final String SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.disable_rest_auth_initially"; + public static final String SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS = SECURITY_SETTINGS_PREFIX + + "unsupported.delay_initialization_seconds"; + public static final String SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.disable_intertransport_auth_initially"; + public static final String SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.passive_intertransport_auth_initially"; + public static final String SECURITY_UNSUPPORTED_RESTORE_SECURITYINDEX_ENABLED = SECURITY_SETTINGS_PREFIX + + "unsupported.restore.securityindex.enabled"; + public static final String SECURITY_UNSUPPORTED_INJECT_USER_ENABLED = SECURITY_SETTINGS_PREFIX + "unsupported.inject_user.enabled"; + public static final String SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED = SECURITY_SETTINGS_PREFIX + + "unsupported.inject_user.admin.enabled"; + public static final String SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS = SECURITY_SETTINGS_PREFIX + "unsupported.allow_now_in_dls"; + + public static final String SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION = SECURITY_SETTINGS_PREFIX + + "unsupported.restapi.allow_securityconfig_modification"; + public static final String SECURITY_UNSUPPORTED_LOAD_STATIC_RESOURCES = SECURITY_SETTINGS_PREFIX + "unsupported.load_static_resources"; + public static final String SECURITY_UNSUPPORTED_ACCEPT_INVALID_CONFIG = SECURITY_SETTINGS_PREFIX + "unsupported.accept_invalid_config"; + + public static final String SECURITY_PROTECTED_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.enabled"; public static final Boolean SECURITY_PROTECTED_INDICES_ENABLED_DEFAULT = false; - public static final String SECURITY_PROTECTED_INDICES_KEY = "plugins.security.protected_indices.indices"; + public static final String SECURITY_PROTECTED_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.indices"; public static final List SECURITY_PROTECTED_INDICES_DEFAULT = Collections.emptyList(); - public static final String SECURITY_PROTECTED_INDICES_ROLES_KEY = "plugins.security.protected_indices.roles"; + public static final String SECURITY_PROTECTED_INDICES_ROLES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.roles"; public static final List SECURITY_PROTECTED_INDICES_ROLES_DEFAULT = Collections.emptyList(); // Roles injection for plugins @@ -352,19 +358,20 @@ public enum RolesMappingResolution { // System indices settings public static final String SYSTEM_INDEX_PERMISSION = "system:admin/system_index"; - public static final String SECURITY_SYSTEM_INDICES_ENABLED_KEY = "plugins.security.system_indices.enabled"; + public static final String SECURITY_SYSTEM_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.enabled"; public static final Boolean SECURITY_SYSTEM_INDICES_ENABLED_DEFAULT = false; - public static final String SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY = "plugins.security.system_indices.permission.enabled"; + public static final String SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + + "system_indices.permission.enabled"; public static final Boolean SECURITY_SYSTEM_INDICES_PERMISSIONS_DEFAULT = false; - public static final String SECURITY_SYSTEM_INDICES_KEY = "plugins.security.system_indices.indices"; + public static final String SECURITY_SYSTEM_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.indices"; public static final List SECURITY_SYSTEM_INDICES_DEFAULT = Collections.emptyList(); - public static final String SECURITY_MASKED_FIELDS_ALGORITHM_DEFAULT = "plugins.security.masked_fields.algorithm.default"; + public static final String SECURITY_MASKED_FIELDS_ALGORITHM_DEFAULT = SECURITY_SETTINGS_PREFIX + "masked_fields.algorithm.default"; public static final String TENANCY_PRIVATE_TENANT_NAME = "private"; public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; - public static final String USE_JDK_SERIALIZATION = "plugins.security.use_jdk_serialization"; + public static final String USE_JDK_SERIALIZATION = SECURITY_SETTINGS_PREFIX + "use_jdk_serialization"; // On-behalf-of endpoints settings // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings From 6b83ebf9dceb30997ea893530aee1161f7823254 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 17 Mar 2025 17:37:28 -0400 Subject: [PATCH 2/4] Introduces a resource sharing client and completes resource access control implementation in common package Signed-off-by: Darshit Chanpura --- .github/workflows/ci.yml | 37 +- RESOURCE_ACCESS_CONTROL_FOR_PLUGINS.md | 464 ++++++ build.gradle | 5 +- client/README.md | 233 +++ client/build.gradle | 101 ++ .../resources/ResourceSharingClient.java | 65 + .../resources/ResourceSharingNodeClient.java | 186 +++ .../client/resources/package-info.java | 14 + common/build.gradle | 91 ++ .../security/common/DefaultObjectMapper.java | 298 ++++ .../common/auditlog/impl/AuditCategory.java | 40 + .../common}/auth/UserSubjectImpl.java | 12 +- .../common/configuration/AdminDNs.java | 162 ++ .../common/dlic/rest/api/Responses.java | 106 ++ .../security/common/package-info.java | 15 + .../resources/ResourceAccessHandler.java | 549 +++++++ .../resources/ResourceIndexListener.java | 123 ++ .../common/resources/ResourcePluginInfo.java | 58 + .../common/resources/ResourceProvider.java | 21 + .../resources/ResourceSharingConstants.java | 21 + .../ResourceSharingIndexHandler.java | 1402 +++++++++++++++++ ...ourceSharingIndexManagementRepository.java | 59 + .../resources/rest/ResourceAccessAction.java | 28 + .../resources/rest/ResourceAccessRequest.java | 236 +++ .../rest/ResourceAccessRequestParams.java | 32 + .../rest/ResourceAccessResponse.java | 98 ++ .../rest/ResourceAccessRestAction.java | 151 ++ .../rest/ResourceAccessTransportAction.java | 117 ++ .../common/support/ConfigConstants.java | 404 +++++ .../security/common/support/Utils.java | 285 ++++ .../common/support/WildcardMatcher.java | 556 +++++++ .../security/common/user/AuthCredentials.java | 254 +++ .../common/user/CustomAttributesAware.java | 34 + .../opensearch/security/common/user/User.java | 312 ++++ scripts/build.sh | 2 + settings.gradle | 6 + .../security/OpenSearchSecurityPlugin.java | 105 +- .../security/auth/BackendRegistry.java | 25 +- .../security/dlic/rest/support/Utils.java | 2 + .../security/support/ConfigConstants.java | 4 + .../security/IndexIntegrationTests.java | 11 +- .../security/SlowIntegrationTests.java | 1 + .../security/auth/UserSubjectImplTests.java | 3 +- 43 files changed, 6702 insertions(+), 26 deletions(-) create mode 100644 RESOURCE_ACCESS_CONTROL_FOR_PLUGINS.md create mode 100644 client/README.md create mode 100644 client/build.gradle create mode 100644 client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java create mode 100644 client/src/main/java/org/opensearch/security/client/resources/ResourceSharingNodeClient.java create mode 100644 client/src/main/java/org/opensearch/security/client/resources/package-info.java create mode 100644 common/build.gradle create mode 100644 common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java create mode 100644 common/src/main/java/org/opensearch/security/common/auditlog/impl/AuditCategory.java rename {src/main/java/org/opensearch/security => common/src/main/java/org/opensearch/security/common}/auth/UserSubjectImpl.java (83%) create mode 100644 common/src/main/java/org/opensearch/security/common/configuration/AdminDNs.java create mode 100644 common/src/main/java/org/opensearch/security/common/dlic/rest/api/Responses.java create mode 100644 common/src/main/java/org/opensearch/security/common/package-info.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceAccessHandler.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceIndexListener.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourcePluginInfo.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceProvider.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceSharingConstants.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexManagementRepository.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessAction.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequest.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequestParams.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessResponse.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java create mode 100644 common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessTransportAction.java create mode 100644 common/src/main/java/org/opensearch/security/common/support/ConfigConstants.java create mode 100644 common/src/main/java/org/opensearch/security/common/support/Utils.java create mode 100644 common/src/main/java/org/opensearch/security/common/support/WildcardMatcher.java create mode 100644 common/src/main/java/org/opensearch/security/common/user/AuthCredentials.java create mode 100644 common/src/main/java/org/opensearch/security/common/user/CustomAttributesAware.java create mode 100644 common/src/main/java/org/opensearch/security/common/user/User.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b1b82e300..3ed86681fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,8 @@ jobs: run: | ./gradlew clean \ :opensearch-resource-sharing-spi:publishToMavenLocal \ + :opensearch-security-common:publishToMavenLocal \ + :opensearch-security-client:publishToMavenLocal \ -Dbuild.snapshot=false - name: Cache artifacts for dependent jobs @@ -335,31 +337,54 @@ jobs: ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-all.jar ./gradlew clean :opensearch-resource-sharing-spi:publishToMavenLocal -Dbuild.version_qualifier=$test_qualifier && test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT-all.jar + # Publish Common + ./gradlew clean :opensearch-security-common:publishToMavenLocal && test -s ./common/build/libs/opensearch-security-common-$security_plugin_version-all.jar + ./gradlew clean :opensearch-security-common:publishToMavenLocal -Dbuild.snapshot=false && test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_no_snapshot-all.jar + ./gradlew clean :opensearch-security-common:publishToMavenLocal -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_only_number-$test_qualifier-all.jar + ./gradlew clean :opensearch-security-common:publishToMavenLocal -Dbuild.version_qualifier=$test_qualifier && test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT-all.jar + + # Publish Client + ./gradlew clean :opensearch-security-client:publishToMavenLocal && test -s ./client/build/libs/opensearch-security-client-$security_plugin_version-all.jar + ./gradlew clean :opensearch-security-client:publishToMavenLocal -Dbuild.snapshot=false && test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_no_snapshot-all.jar + ./gradlew clean :opensearch-security-client:publishToMavenLocal -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_only_number-$test_qualifier-all.jar + ./gradlew clean :opensearch-security-client:publishToMavenLocal -Dbuild.version_qualifier=$test_qualifier && test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT-all.jar # Build artifacts ./gradlew clean assemble && \ test -s ./build/distributions/opensearch-security-$security_plugin_version.zip && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version.jar && \ + test -s ./client/build/libs/opensearch-security-client-$security_plugin_version.jar + ./gradlew clean assemble -Dbuild.snapshot=false && \ test -s ./build/distributions/opensearch-security-$security_plugin_version_no_snapshot.zip && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_no_snapshot.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_no_snapshot.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_no_snapshot.jar && \ + test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_no_snapshot.jar ./gradlew clean assemble -Dbuild.snapshot=false -Dbuild.version_qualifier=$test_qualifier && \ test -s ./build/distributions/opensearch-security-$security_plugin_version_only_number-$test_qualifier.zip && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_only_number-$test_qualifier.jar && \ + test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_only_number-$test_qualifier.jar ./gradlew clean assemble -Dbuild.version_qualifier=$test_qualifier && \ test -s ./build/distributions/opensearch-security-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.zip && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.jar && \ + test -s ./client/build/libs/opensearch-security-client-$security_plugin_version_only_number-$test_qualifier-SNAPSHOT.jar ./gradlew clean publishPluginZipPublicationToZipStagingRepository && \ test -s ./build/distributions/opensearch-security-$security_plugin_version.zip && \ test -s ./build/distributions/opensearch-security-$security_plugin_version.pom && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version-all.jar ./gradlew clean publishShadowPublicationToMavenLocal && \ - test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar + test -s ./spi/build/libs/opensearch-resource-sharing-spi-$security_plugin_version-all.jar && \ + test -s ./common/build/libs/opensearch-security-common-$security_plugin_version-all.jar && \ + test -s ./client/build/libs/opensearch-security-client-$security_plugin_version-all.jar - name: List files in build directory on failure if: failure() diff --git a/RESOURCE_ACCESS_CONTROL_FOR_PLUGINS.md b/RESOURCE_ACCESS_CONTROL_FOR_PLUGINS.md new file mode 100644 index 0000000000..42c0c61731 --- /dev/null +++ b/RESOURCE_ACCESS_CONTROL_FOR_PLUGINS.md @@ -0,0 +1,464 @@ +# **Resource Sharing and Access Control in OpenSearch** + +This guide provides an **in-depth overview** for **plugin developers**, covering the **features, setup, and utilization** of the **Resource Sharing and Access Control** functionality in OpenSearch. + +## **1. What is the Feature?** +The **Resource Sharing and Access Control** feature in OpenSearch Security Plugin enables fine-grained access management for resources declared by plugins. It allows: +- Users to **share and revoke access** to their own resources. +- **Super admins** to access all resources. +- Plugins to **define and manage resource access** via a standardized interface. + +This feature ensures **secure** and **controlled** access to resources while leveraging existing **index-level authorization** in OpenSearch. + +--- + +## **2. What are the Components?** +This feature introduces **two primary components** for plugin developers: + +### **1. `opensearch-security-client`** +- Provides a client with methods for **resource access control**. +- Plugins must declare a **dependency** on this client to integrate with security features. + +### **2. `opensearch-resource-sharing-spi`** +- A **Service Provider Interface (SPI)** that plugins must implement to declare themselves as **Resource Plugins**. +- The security plugin keeps track of these plugins (similar to how JobScheduler tracks `JobSchedulerExtension`). + +### **Plugin Implementation Requirements:** + +- This feature is marked as **`@opensearch.experimental`** and can be toggled using the feature flag: **`plugins.security.resource_sharing.enabled`**, which is **enabled by default**. +- **Resource indices must be system indices**, and **system index protection must be enabled** (`plugins.security.system_indices.enabled: true`) to prevent unauthorized direct access. +- Plugins must declare dependencies on **`opensearch-security-client`** and **`opensearch-resource-sharing-spi`** in their `build.gradle`. + +### **Plugin Implementation Requirements** +Each plugin must: +- **Declare a dependency** on `opensearch-security-client` package: +```build.gradle +implementation group: 'org.opensearch', name:'opensearch-security-client', version: "${opensearch_build}" +``` +- **Extend** `opensearch-security` plugin with optional flag: +```build.gradle +opensearchplugin { + name '' + description '' + classname '' + extendedPlugins = ['opensearch-security;optional=true', ] +} +``` +- **Implement** the `ResourceSharingExtension` class. +- **Ensure** that its declared resources implement the `Resource` interface. +- **Provide a resource parser**, which the security plugin uses to extract resource details from the resource index. +- **Register itself** in `META-INF/services` by creating the following file: + ``` + src/main/resources/META-INF/services/org.opensearch.security.spi.ResourceSharingExtension + ``` + - This file must contain a **single line** specifying the **fully qualified class name** of the plugin’s `ResourceSharingExtension` implementation, e.g.: + ``` + org.opensearch.sample.SampleResourcePlugin + ``` +--- + +## **3. Feature Flag** +This feature is controlled by the following flag: + +- **Feature flag:** `plugins.security.resource_sharing.enabled` +- **Default value:** `true` +- **How to disable?** Set the flag to `false` in the opensearch configuration: + ```yaml + plugins.security.resource_sharing.enabled: false + ``` + +--- + +## **4. Declaring a Resource Plugin and Using the Client for Access Control** +### **Declaring a Plugin as a Resource Plugin** +To integrate with the security plugin, your plugin must: +1. Extend `ResourceSharingExtension` and implement required methods. +2. Implement the `Resource` interface for resource declaration. +3. Implement a resource parser to extract resource details. + +[`opensearch-resource-sharing-spi` README.md](./spi/README.md) is a great resource to learn more about the components of SPI and how to set up. + +Tip: Refer to the `org.opensearch.sample.SampleResourcePlugin` class to understand the setup in further detail. + +Example usage: +```java + +public class SampleResourcePlugin extends Plugin implements SystemIndexPlugin, ResourceSharingExtension { + + // override any required methods + + @Override + public Collection getSystemIndexDescriptors(Settings settings) { + final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Sample index with resources"); + return Collections.singletonList(systemIndexDescriptor); + } + + @Override + public String getResourceType() { + return SampleResource.class.getCanonicalName(); + } + + @Override + public String getResourceIndex() { + return RESOURCE_INDEX_NAME; + } + + @Override + public ResourceParser getResourceParser() { + return new SampleResourceParser(); + } +} +``` + + +### **Calling Access Control Methods from the ResourceSharingClient Client** +Plugins must **declare a dependency** on `opensearch-security-client` and use it to call access control methods. +The client provides **four access control methods** for plugins. For detailed usage and implementation, refer to the [`opensearch-security-client` README.md](./client/README.md) + + +Tip: Refer to the `org.opensearch.sample.resource.client.ResourceSharingClientAccessor` class to understand the client setup in further detail. + +Example usage: +```java + @Override +void doExecute(Task task, ShareResourceRequest request, ActionListener listener) { + if (request.getResourceId() == null || request.getResourceId().isEmpty()) { + listener.onFailure(new IllegalArgumentException("Resource ID cannot be null or empty")); + return; + } + + ResourceSharingClient resourceSharingClient = ResourceSharingClientAccessor.getResourceSharingClient(nodeClient, settings); + resourceSharingClient.shareResource( + request.getResourceId(), + RESOURCE_INDEX_NAME, + request.getShareWith(), + ActionListener.wrap(sharing -> { + ShareResourceResponse response = new ShareResourceResponse(sharing.getShareWith()); + listener.onResponse(response); + }, listener::onFailure) + ); +} +``` + + +--- + +## **5. What are Scopes?** + +This feature introduces a new **sharing mechanism** called **scopes**. Scopes define **the level of access** granted to users for a resource. They are **defined and maintained by plugins**, and the security plugin does **not** interpret or enforce their specific meanings. This approach gives plugins the **flexibility** to define scope names and behaviors based on their use case. + +Each plugin must **document its scope definitions** so that users understand the **sharing semantics** and how different scopes affect access control. + +Scopes enable **granular access control**, allowing resources to be shared with **customized permission levels**, making the system more flexible and adaptable to different use cases. + +### **Common Scopes for Plugins to declare** +| Scope | Description | +|-------------|-----------------------------------------------------| +| `PUBLIC` | The resource is accessible to all users. | +| `READ_ONLY` | Users can view but not modify the resource. | +| `READ_WRITE` | Users can view and modify the resource. | + +By default, all resources are private and only visible to the owner and super-admins. Resources become accessible to others only when explicitly shared. + +SPI provides you an interface, with two default scopes `PUBLIC` and `RESTRICTED`, which can be extended to introduce more plugin-specific values. + +### **Using Scopes in API Design** +- APIs should be logically paired with correct scopes. + - Example, **GET APIs** should be logically paired with **`READ_ONLY`**, **`READ_WRITE`**, or **`PUBLIC`** scopes. When verifying access, these scopes must be **passed to the security plugin** via the `ResourceSharingNodeClient` to determine whether a user has the required permissions. + + +--- + +## **6. User Setup** + +To enable users to interact with the **Resource Sharing and Access Control** feature, they must be assigned the appropriate cluster permissions along with resource-specific access. + +### **Required Cluster Permissions** +Users must be assigned the following **cluster permissions** in `roles.yml`: + +- **`cluster:admin/security/resource_access`** → Required to evaluate resource permissions. +- **Plugin-specific cluster permissions** → Required to interact with the plugin’s APIs. + +#### **Example Role Configurations** +```yaml +sample_full_access: + cluster_permissions: + - 'cluster:admin/security/resource_access' + - 'cluster:admin/sample-resource-plugin/*' + +sample_read_access: + cluster_permissions: + - 'cluster:admin/security/resource_access' + - 'cluster:admin/sample-resource-plugin/get' +``` + + +### **User Access Rules** +1. **Users must have the required cluster permissions** + - Even if a resource is shared with a user, they **cannot access it** unless they have the **plugin’s cluster permissions**. + +2. **Granting plugin API permissions does not automatically grant resource access** + - A resource must be **explicitly shared** with the user. + - **Or, the user must be the resource owner.** + +3. **No index permissions are required** + - Access control is **handled at the cluster level**. + - The `.opensearch_resource_sharing` index and the resource indices are protected under system index security. + + +### **Summary** +| **Requirement** | **Description** | +|---------------|---------------------------------------------------------------------------------------| +| **Cluster Permission** | `cluster:admin/security/resource_access` required for resource evaluation. | +| **Plugin API Permissions** | Users must also have relevant plugin API cluster permissions. | +| **Resource Sharing** | Access is granted only if the resource is shared with the user or they are the owner. | +| **No Index Permissions Needed** | The `.opensearch_resource_sharing` index and resource indices are system-protected. | + + +--- + +## **7. Restrictions** +1. At present, **only resource owners can share/revoke access** to their own resources. + - **Super admins** can manage access for any resource. +2. **Resources must be stored in a system index**, and system index protection **must be enabled**. + - **Disabling system index protection** allows users to access resources **directly** if they have relevant index permissions. + +--- + +## **8. REST APIs Introduced by the Security Plugin** + +In addition to client methods, the **Security Plugin** introduces new **REST APIs** for managing resource access when the feature is enabled. These APIs allow users to **verify, grant, revoke, and list access** to resources. + +--- + +### **1. Verify Access** +- **Endpoint:** + ``` + POST /_plugins/_security/resources/verify_access + ``` +- **Description:** + Verifies whether the current user has access to a specified resource within the given index and scopes. + +#### **Request Body:** +```json +{ + "resource_id": "my-resource", + "resource_index": "resource-index", + "scopes": ["READ_ONLY"] +} +``` + +#### **Request Fields:** +| Field | Type | Description | +|-----------------|----------|-------------| +| `resource_id` | String | Unique identifier of the resource being accessed. | +| `resource_index`| String | The OpenSearch index where the resource is stored. | +| `scopes` | Array | The list of scopes to check access against (e.g., `"READ_ONLY"`, `"READ_WRITE"`). | + +#### **Response:** +Returns whether the user has permission to access the resource. +```json +{ + "has_permission": true +} +``` + +#### **Response Fields:** +| Field | Type | Description | +|-----------------|---------|-------------| +| `has_permission` | Boolean | `true` if the user has access, `false` otherwise. | + +--- + +### **2. Grant Access** +- **Endpoint:** + ``` + POST /_plugins/_security/resources/share + ``` +- **Description:** + Grants access to a resource for specified **users, roles, and backend roles** under defined **scopes**. + +#### **Request Body:** +```json +{ + "resource_id": "my-resource", + "resource_index": "resource-index", + "share_with": { + "your-scope-name": { + "users": ["shared-user-name"], + "backend_roles": ["shared-backend-roles"] + }, + "your-scope-name-2": { + "roles": ["shared-roles"] + } + } +} +``` + +#### **Request Fields:** +| Field | Type | Description | +|-----------------|---------|-------------| +| `resource_id` | String | The unique identifier of the resource to be shared. | +| `resource_index`| String | The OpenSearch index where the resource is stored. | +| `share_with` | Object | Defines which **users, roles, or backend roles** will gain access. | +| `your-scope-name` | Object | The scope under which the resource is shared (e.g., `"READ_ONLY"`, `"PUBLIC"`). | +| `users` | Array | List of usernames allowed to access the resource. | +| `roles` | Array | List of role names granted access. | +| `backend_roles`| Array | List of backend roles assigned to the resource. | + +#### **Response:** +Returns the updated **resource sharing state**. +```json +{ + "sharing_info": { + "source_idx": "resource-index", + "resource_id": "my-resource", + "created_by": { + "user": "you" + }, + "share_with": { + "your-scope-name": { + "users": ["shared-user-name"], + "backend_roles": ["shared-backend-roles"] + }, + "your-scope-name-2": { + "roles": ["shared-roles"] + } + } + } +} +``` + +#### **Response Fields:** +| Field | Type | Description | +|---------------|---------|-------------| +| `sharing_info` | Object | Contains information about how the resource is shared. | +| `source_idx` | String | The OpenSearch index containing the resource. | +| `resource_id` | String | The unique identifier of the resource being shared. | +| `created_by` | Object | Information about the user who created the sharing entry. | +| `share_with` | Object | Defines users, roles, and backend roles with access to the resource. | + +--- + +### **3. Revoke Access** +- **Endpoint:** + ``` + POST /_plugins/_security/resources/revoke + ``` +- **Description:** + Revokes access to a resource for specific users, roles, or backend roles under certain scopes. + +#### **Request Body:** +```json +{ + "resource_id": "my-resource", + "resource_index": "resource-index", + "entities_to_revoke": { + "roles": ["shared-roles"] + }, + "scopes": ["your-scope-name-2"] +} +``` + +#### **Request Fields:** +| Field | Type | Description | +|-----------------|---------|-------------| +| `resource_id` | String | The unique identifier of the resource whose access is being revoked. | +| `resource_index`| String | The OpenSearch index where the resource is stored. | +| `entities_to_revoke` | Object | Specifies which **users, roles, or backend roles** should have their access removed. | +| `roles` | Array | List of roles to revoke access from. | +| `scopes` | Array | List of scopes from which access should be revoked. | + +#### **Response:** +Returns the updated **resource sharing state** after revocation. +```json +{ + "sharing_info": { + "source_idx": "resource-index", + "resource_id": "my-resource", + "created_by": { + "user": "admin" + }, + "share_with": { + "your-scope-name": { + "users": ["shared-user-name"], + "backend_roles": ["shared-backend-roles"] + } + } + } +} +``` + +#### **Response Fields:** +| Field | Type | Description | +|---------------|---------|-------------| +| `sharing_info` | Object | Contains information about the updated resource sharing state. | +| `source_idx` | String | The OpenSearch index containing the resource. | +| `resource_id` | String | The unique identifier of the resource. | +| `created_by` | Object | Information about the user who created the sharing entry. | +| `share_with` | Object | Defines users, roles, and backend roles that still have access to the resource. | + +--- + +### **4. List Accessible Resources** +- **Endpoint:** + ``` + GET /_plugins/_security/resources/list/{resource_index} + ``` +- **Description:** + Retrieves a list of **resources that the current user has access to** within the specified `{resource_index}`. + +#### **Response:** +Returns an array of accessible resources. +```json +{ + "resources": [ + { + "name": "my-resource-name", + "description": "My resource description.", + "attributes": { + "type": "model" + } + } + ] +} +``` +*This is an example resource. Actual structure will vary based on your configuration.* + +--- + +## **Additional Notes** +- **Feature Flag:** These APIs are available only when `plugins.security.resource_sharing.enabled` is set to `true` in the configuration. +- **Index Restrictions:** Resources must be stored in **system indices**, and **system index protection** must be enabled to prevent unauthorized access. +- **Scopes Flexibility:** The `share_with` field allows defining **custom access scopes** as per plugin requirements. + +--- + +## **9. Best Practices** +### **For Plugin Developers** +- **Declare resources properly** in the `ResourceSharingExtension`. +- **Use the security client** instead of direct index queries to check access. +- **Implement a resource parser** to ensure correct resource extraction. + +### **For Users & Admins** +- **Keep system index protection enabled** for better security. +- **Grant access only when necessary** to limit exposure. + +--- + +## **Conclusion** +The **Resource Sharing and Access Control** feature enhances OpenSearch security by introducing an **additional layer of fine-grained access management** for plugin-defined resources. While **Fine-Grained Access Control (FGAC)** is already enabled, this feature provides **even more granular control** specifically for **resource-level access** within plugins. + +By implementing the **Service Provider Interface (SPI)**, utilizing the **security client**, and following **best practices**, developers can seamlessly integrate this feature into their plugins to enforce controlled resource sharing and access management. + +For detailed implementation and examples, refer to the **[sample plugin](./sample-resource-plugin/README.md)** included in the security plugin repository. + +--- + +## **License** +This project is licensed under the **Apache 2.0 License**. + +--- + +## **Copyright** +© OpenSearch Contributors. diff --git a/build.gradle b/build.gradle index 9d803c03f2..0b52259149 100644 --- a/build.gradle +++ b/build.gradle @@ -569,6 +569,8 @@ allprojects { integrationTestImplementation 'com.selectivem.collections:special-collections-complete:1.4.0' integrationTestImplementation "org.opensearch.plugin:lang-painless:${opensearch_version}" integrationTestImplementation project(path:":opensearch-resource-sharing-spi", configuration: 'shadow') + integrationTestImplementation project(path: ":${rootProject.name}-common", configuration: 'shadow') + integrationTestImplementation project(path: ":${rootProject.name}-client", configuration: 'shadow') } } @@ -640,7 +642,7 @@ tasks.integrationTest.finalizedBy(jacocoTestReport) // report is always generate check.dependsOn integrationTest dependencies { - implementation project(path:":opensearch-resource-sharing-spi", configuration: 'shadow') + implementation project(path: ":${rootProject.name}-common", configuration: 'shadow') implementation "org.opensearch.plugin:transport-netty4-client:${opensearch_version}" implementation "org.opensearch.client:opensearch-rest-high-level-client:${opensearch_version}" implementation "org.apache.httpcomponents.client5:httpclient5-cache:${versions.httpclient5}" @@ -801,6 +803,7 @@ dependencies { exclude group: 'com.google.guava' } + testImplementation project(path: ":${rootProject.name}-common", configuration: 'shadow') } jar { diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000000..2f944adb35 --- /dev/null +++ b/client/README.md @@ -0,0 +1,233 @@ +Here's a **refined and corrected** version of your `README.md` file with improved clarity, grammar, and formatting: + +--- + +# **Resource Sharing Client** + +This package provides a **ResourceSharing client** that resource plugins can use to **implement access control** by communicating with the **OpenSearch Security Plugin**. + +--- + +## **Usage** + +### **1. Creating a Client Accessor with Singleton Pattern** +To ensure a single instance of the `ResourceSharingNodeClient`, use the **Singleton pattern**: + +```java +public class ResourceSharingClientAccessor { + private static ResourceSharingNodeClient INSTANCE; + + private ResourceSharingClientAccessor() {} + + /** + * Get the resource sharing client instance. + * + * @param nodeClient The OpenSearch NodeClient instance. + * @param settings The OpenSearch settings. + * @return A singleton instance of ResourceSharingNodeClient. + */ + public static ResourceSharingNodeClient getResourceSharingClient(NodeClient nodeClient, Settings settings) { + if (INSTANCE == null) { + INSTANCE = new ResourceSharingNodeClient(nodeClient, settings); + } + return INSTANCE; + } +} +``` + +--- + +### **2. Using the Client in a Transport Action** +The following example demonstrates how to use the **Resource Sharing Client** inside a `TransportAction` to verify **delete permissions** before deleting a resource. + +```java +@Override +protected void doExecute(Task task, DeleteResourceRequest request, ActionListener listener) { + String resourceId = request.getResourceId(); + + ResourceSharingClient resourceSharingClient = ResourceSharingClientAccessor.getResourceSharingClient(nodeClient, settings); + + resourceSharingClient.verifyResourceAccess( + resourceId, + RESOURCE_INDEX_NAME, + SampleResourceScope.PUBLIC.value(), + ActionListener.wrap(isAuthorized -> { + if (!isAuthorized) { + listener.onFailure(new ResourceSharingException("Current user is not authorized to delete resource: " + resourceId)); + return; + } + + // Authorization successful, proceed with deletion + ThreadContext threadContext = transportService.getThreadPool().getThreadContext(); + try (ThreadContext.StoredContext ignored = threadContext.stashContext()) { + deleteResource(resourceId, ActionListener.wrap(deleteResponse -> { + if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { + listener.onFailure(new ResourceNotFoundException("Resource " + resourceId + " not found.")); + } else { + listener.onResponse(new DeleteResourceResponse("Resource " + resourceId + " deleted successfully.")); + } + }, exception -> { + log.error("Failed to delete resource: " + resourceId, exception); + listener.onFailure(exception); + })); + } + }, exception -> { + log.error("Failed to verify resource access: " + resourceId, exception); + listener.onFailure(exception); + }) + ); +} +``` + +--- + +## **Available Java APIs** + +The **`ResourceSharingClient`** provides **four Java APIs** for **resource access control**, enabling plugins to **verify, share, revoke, and list** resources. + +**Package Location:** +[`org.opensearch.security.client.resources.ResourceSharingClient`](../client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java) + +--- + +### **API Usage Examples** +Below are examples demonstrating how to use each API effectively. + +--- + +### **1. `verifyResourceAccess`** +**Checks if the current user has access to a resource** based on predefined **scopes**. + +#### **Method Signature:** +```java +void verifyResourceAccess(String resourceId, String resourceIndex, Set scopes, ActionListener listener); +``` + +#### **Example Usage:** +```java +Set scopes = Set.of("READ_ONLY"); +resourceSharingClient.verifyResourceAccess( + "resource-123", + "resource_index", + scopes, + ActionListener.wrap(isAuthorized -> { + if (isAuthorized) { + System.out.println("User has access to the resource."); + } else { + System.out.println("Access denied."); + } + }, e -> { + System.err.println("Failed to verify access: " + e.getMessage()); + }) +); +``` +> **Use Case:** Before performing operations like **deletion or modifications**, ensure the user has the right permissions. + +--- + +### **2. `shareResource`** +**Grants access to a resource** for specific users, roles, or backend roles. + +#### **Method Signature:** +```java +void shareResource(String resourceId, String resourceIndex, Map shareWith, ActionListener listener); +``` + +#### **Example Usage:** +```java +Map shareWith = Map.of( + "users", List.of("user_1", "user_2"), + "roles", List.of("admin_role"), + "backend_roles", List.of("backend_group") +); + +resourceSharingClient.shareResource( + "resource-123", + "resource_index", + shareWith, + ActionListener.wrap(response -> { + System.out.println("Resource successfully shared with: " + shareWith); + }, e -> { + System.err.println("Failed to share resource: " + e.getMessage()); + }) +); +``` +> **Use Case:** Used when an **owner/admin wants to share a resource** with specific users or groups. + +--- + +### **3. `revokeResourceAccess`** +**Removes access permissions** for specified users, roles, or backend roles. + +#### **Method Signature:** +```java +void revokeResourceAccess(String resourceId, String resourceIndex, Map entitiesToRevoke, Set scopes, ActionListener listener); +``` + +#### **Example Usage:** +```java +Map entitiesToRevoke = Map.of( + "users", List.of("user_2"), + "roles", List.of("viewer_role") +); +Set scopesToRevoke = Set.of("READ_ONLY"); + +resourceSharingClient.revokeResourceAccess( + "resource-123", + "resource_index", + entitiesToRevoke, + scopesToRevoke, + ActionListener.wrap(response -> { + System.out.println("Resource access successfully revoked for: " + entitiesToRevoke); + }, e -> { + System.err.println("Failed to revoke access: " + e.getMessage()); + }) +); +``` +> **Use Case:** When a user no longer needs access to a **resource**, their permissions can be revoked. + +--- + +### **4. `listAllAccessibleResources`** +**Retrieves all resources the current user has access to.** + +#### **Method Signature:** +```java +void listAllAccessibleResources(String resourceIndex, ActionListener> listener); +``` + +#### **Example Usage:** +```java +resourceSharingClient.listAllAccessibleResources( + "resource_index", + ActionListener.wrap(resources -> { + for (Resource resource : resources) { + System.out.println("Accessible Resource: " + resource.getId()); + } + }, e -> { + System.err.println("Failed to list accessible resources: " + e.getMessage()); + }) +); +``` +> **Use Case:** Helps a user identify **which resources they can interact with**. + +--- + +## **Conclusion** +These APIs provide essential methods for **fine-grained resource access control**, enabling: + +✔ **Verification** of resource access. +✔ **Granting and revoking** access dynamically. +✔ **Retrieval** of all accessible resources. + +For further details, refer to the [`ResourceSharingClient` Java class](../client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java). + +--- + +## **License** +This project is licensed under the **Apache 2.0 License**. + +--- + +## **Copyright** +© OpenSearch Contributors. diff --git a/client/build.gradle b/client/build.gradle new file mode 100644 index 0000000000..8bef3910bc --- /dev/null +++ b/client/build.gradle @@ -0,0 +1,101 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id 'java' + id 'maven-publish' + id 'io.github.goooler.shadow' version "8.1.7" +} + +ext { + opensearch_version = System.getProperty("opensearch.version", "3.0.0-alpha1-SNAPSHOT") + isSnapshot = "true" == System.getProperty("build.snapshot", "true") + buildVersionQualifier = System.getProperty("build.version_qualifier", "alpha1") + + // 2.0.0-rc1-SNAPSHOT -> 2.0.0.0-rc1-SNAPSHOT + version_tokens = opensearch_version.tokenize('-') + opensearch_build = version_tokens[0] + '.0' + + if (buildVersionQualifier) { + opensearch_build += "-${buildVersionQualifier}" + } + if (isSnapshot) { + opensearch_build += "-SNAPSHOT" + } +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } +} + +dependencies { + compileOnly "org.opensearch:opensearch:${opensearch_version}" + // SPI dependency comes through common + implementation project(path: ":${rootProject.name}-common", configuration: 'shadow') +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +task sourcesJar(type: Jar) { + archiveClassifier.set 'sources' + from sourceSets.main.allJava +} + +task javadocJar(type: Jar) { + archiveClassifier.set 'javadoc' + from tasks.javadoc +} + +publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifact sourcesJar + artifact javadocJar + pom { + name.set("OpenSearch Security Client") + packaging = "jar" + description.set("OpenSearch Security Client") + url.set("https://github.com/opensearch-project/security") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + scm { + connection.set("scm:git@github.com:opensearch-project/security.git") + developerConnection.set("scm:git@github.com:opensearch-project/security.git") + url.set("https://github.com/opensearch-project/security.git") + } + developers { + developer { + name.set("OpenSearch Contributors") + url.set("https://github.com/opensearch-project") + } + } + } + } + } + repositories { + maven { + name = "Snapshots" + url = "https://aws.oss.sonatype.org/content/repositories/snapshots" + credentials { + username "$System.env.SONATYPE_USERNAME" + password "$System.env.SONATYPE_PASSWORD" + } + } + maven { + name = 'staging' + url = "${rootProject.buildDir}/local-staging-repo" + } + } +} diff --git a/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java b/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java new file mode 100644 index 0000000000..615f27ed68 --- /dev/null +++ b/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingClient.java @@ -0,0 +1,65 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.client.resources; + +import java.util.Map; +import java.util.Set; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; + +/** + * Interface for resource sharing client operations. + * + * @opensearch.experimental + */ +public interface ResourceSharingClient { + + /** + * Verifies if the current user has access to the specified resource. + * @param resourceId The ID of the resource to verify access for. + * @param resourceIndex The index containing the resource. + * @param scopes The scopes to be checked against. + * @param listener The listener to be notified with the access verification result. + */ + void verifyResourceAccess(String resourceId, String resourceIndex, Set scopes, ActionListener listener); + + /** + * Shares a resource with the specified users, roles, and backend roles. + * @param resourceId The ID of the resource to share. + * @param resourceIndex The index containing the resource. + * @param shareWith The users, roles, and backend roles to share the resource with. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + void shareResource(String resourceId, String resourceIndex, Map shareWith, ActionListener listener); + + /** + * Revokes access to a resource for the specified entities and scopes. + * @param resourceId The ID of the resource to revoke access for. + * @param resourceIndex The index containing the resource. + * @param entitiesToRevoke The entities to revoke access for. + * @param scopes The scopes to revoke access for. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + void revokeResourceAccess( + String resourceId, + String resourceIndex, + Map entitiesToRevoke, + Set scopes, + ActionListener listener + ); + + /** + * Lists all resources accessible by the current user. + * @param resourceIndex The index containing the resources. + * @param listener The listener to be notified with the set of accessible resources. + */ + void listAllAccessibleResources(String resourceIndex, ActionListener> listener); +} diff --git a/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingNodeClient.java b/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingNodeClient.java new file mode 100644 index 0000000000..239e23e128 --- /dev/null +++ b/client/src/main/java/org/opensearch/security/client/resources/ResourceSharingNodeClient.java @@ -0,0 +1,186 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.client.resources; + +import java.util.Map; +import java.util.Set; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.common.settings.Settings; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.security.common.resources.rest.ResourceAccessAction; +import org.opensearch.security.common.resources.rest.ResourceAccessRequest; +import org.opensearch.security.common.resources.rest.ResourceAccessResponse; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.exceptions.ResourceSharingException; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; +import org.opensearch.transport.client.Client; + +/** + * Client for resource sharing operations. + * + * @opensearch.experimental + */ +public final class ResourceSharingNodeClient implements ResourceSharingClient { + + private static final Logger log = LogManager.getLogger(ResourceSharingNodeClient.class); + + private final Client client; + private final boolean resourceSharingEnabled; + private final boolean isSecurityDisabled; + + public ResourceSharingNodeClient(Client client, Settings settings) { + this.client = client; + this.resourceSharingEnabled = settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + ); + this.isSecurityDisabled = settings.getAsBoolean( + ConfigConstants.OPENSEARCH_SECURITY_DISABLED, + ConfigConstants.OPENSEARCH_SECURITY_DISABLED_DEFAULT + ); + } + + /** + * Verifies if the current user has access to the specified resource. + * @param resourceId The ID of the resource to verify access for. + * @param resourceIndex The index containing the resource. + * @param scopes The scopes to be checked against. + * @param listener The listener to be notified with the access verification result. + */ + @Override + public void verifyResourceAccess(String resourceId, String resourceIndex, Set scopes, ActionListener listener) { + if (isSecurityDisabled || !resourceSharingEnabled) { + String message = isSecurityDisabled ? "Security Plugin is disabled." : "Resource Access Control feature is disabled."; + + log.warn("{} {}", message, "Access to resource is automatically granted"); + listener.onResponse(true); + return; + } + ResourceAccessRequest request = new ResourceAccessRequest.Builder().operation(ResourceAccessRequest.Operation.VERIFY) + .resourceId(resourceId) + .resourceIndex(resourceIndex) + .scopes(scopes) + .build(); + client.execute(ResourceAccessAction.INSTANCE, request, verifyAccessResponseListener(listener)); + } + + /** + * Shares the specified resource with the given users, roles, and backend roles. + * @param resourceId The ID of the resource to share. + * @param resourceIndex The index containing the resource. + * @param shareWith The users, roles, and backend roles to share the resource with. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + @Override + public void shareResource( + String resourceId, + String resourceIndex, + Map shareWith, + ActionListener listener + ) { + if (isResourceAccessControlOrSecurityPluginDisabled("Resource is not shareable.", listener)) { + return; + } + ResourceAccessRequest request = new ResourceAccessRequest.Builder().operation(ResourceAccessRequest.Operation.SHARE) + .resourceId(resourceId) + .resourceIndex(resourceIndex) + .shareWith(shareWith) + .build(); + client.execute(ResourceAccessAction.INSTANCE, request, sharingInfoResponseListener(listener)); + } + + /** + * Revokes access to the specified resource for the given entities and scopes. + * @param resourceId The ID of the resource to revoke access for. + * @param resourceIndex The index containing the resource. + * @param entitiesToRevoke The entities to revoke access for. + * @param scopes The scopes to revoke access for. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + @Override + public void revokeResourceAccess( + String resourceId, + String resourceIndex, + Map entitiesToRevoke, + Set scopes, + ActionListener listener + ) { + if (isResourceAccessControlOrSecurityPluginDisabled("Resource access is not revoked.", listener)) { + return; + } + ResourceAccessRequest request = new ResourceAccessRequest.Builder().operation(ResourceAccessRequest.Operation.REVOKE) + .resourceId(resourceId) + .resourceIndex(resourceIndex) + .revokedEntities(entitiesToRevoke) + .scopes(scopes) + .build(); + client.execute(ResourceAccessAction.INSTANCE, request, sharingInfoResponseListener(listener)); + } + + /** + * Lists all resources accessible by the current user. + * + * @param listener The listener to be notified with the set of accessible resources. + */ + @Override + public void listAllAccessibleResources(String resourceIndex, ActionListener> listener) { + if (isResourceAccessControlOrSecurityPluginDisabled("Unable to list all accessible resources.", listener)) { + return; + } + ResourceAccessRequest request = new ResourceAccessRequest.Builder().operation(ResourceAccessRequest.Operation.LIST) + .resourceIndex(resourceIndex) + .build(); + client.execute( + ResourceAccessAction.INSTANCE, + request, + ActionListener.wrap(response -> { listener.onResponse(response.getResources()); }, listener::onFailure) + ); + } + + /** + * Checks if resource sharing or the security plugin is disabled and handles the error accordingly. + * + * @param disabledMessage The message to be logged if the feature is disabled. + * @param listener The listener to be notified with the error. + * @return {@code true} if either resource sharing or the security plugin is disabled, otherwise {@code false}. + */ + private boolean isResourceAccessControlOrSecurityPluginDisabled(String disabledMessage, ActionListener listener) { + if (isSecurityDisabled || !resourceSharingEnabled) { + String message = (isSecurityDisabled ? "Security Plugin" : "Resource Access Control feature") + " is disabled."; + + log.warn("{} {}", message, disabledMessage); + listener.onFailure(new ResourceSharingException(message + " " + disabledMessage, RestStatus.NOT_IMPLEMENTED)); + return true; + } + return false; + } + + /** + * Notifies the listener with the access request result. + * @param listener The listener to be notified with the access request result. + * @return An ActionListener that handles the ResourceAccessResponse and notifies the listener. + */ + private ActionListener verifyAccessResponseListener(ActionListener listener) { + return ActionListener.wrap(response -> listener.onResponse(response.getHasPermission()), listener::onFailure); + } + + /** + * Notifies the listener with the updated ResourceSharing document. + * @param listener The listener to be notified with the updated ResourceSharing document. + * @return An ActionListener that handles the ResourceAccessResponse and notifies the listener. + */ + private ActionListener sharingInfoResponseListener(ActionListener listener) { + return ActionListener.wrap(response -> listener.onResponse(response.getResourceSharing()), listener::onFailure); + } +} diff --git a/client/src/main/java/org/opensearch/security/client/resources/package-info.java b/client/src/main/java/org/opensearch/security/client/resources/package-info.java new file mode 100644 index 0000000000..1e15c4c46d --- /dev/null +++ b/client/src/main/java/org/opensearch/security/client/resources/package-info.java @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +/** + * This package defines a resource sharing client that will be utilized by resource plugins to call security plugin's transport actions, which handle resource access + * + * @opensearch.experimental + */ +package org.opensearch.security.client.resources; diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000000..2b8e67add5 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,91 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id 'java' + id 'maven-publish' + id 'io.github.goooler.shadow' version "8.1.7" +} + +ext { + opensearch_version = System.getProperty("opensearch.version", "3.0.0-alpha1-SNAPSHOT") +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } +} + +dependencies { + compileOnly "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}" + compileOnly "org.opensearch.plugin:lang-painless:${opensearch_version}" + implementation project(path: ":opensearch-resource-sharing-spi", configuration: 'shadow') + compileOnly "org.apache.commons:commons-lang3:${versions.commonslang}" + compileOnly 'com.password4j:password4j:1.8.2' + compileOnly "com.google.guava:guava:${guava_version}" +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +task sourcesJar(type: Jar) { + archiveClassifier.set 'sources' + from sourceSets.main.allJava +} + +task javadocJar(type: Jar) { + archiveClassifier.set 'javadoc' + from tasks.javadoc +} + +publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifact sourcesJar + artifact javadocJar + pom { + name.set("OpenSearch Security Common") + packaging = "jar" + description.set("OpenSearch Security Common") + url.set("https://github.com/opensearch-project/security") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + scm { + connection.set("scm:git@github.com:opensearch-project/security.git") + developerConnection.set("scm:git@github.com:opensearch-project/security.git") + url.set("https://github.com/opensearch-project/security.git") + } + developers { + developer { + name.set("OpenSearch Contributors") + url.set("https://github.com/opensearch-project") + } + } + } + } + } + repositories { + maven { + name = "Snapshots" + url = "https://aws.oss.sonatype.org/content/repositories/snapshots" + credentials { + username "$System.env.SONATYPE_USERNAME" + password "$System.env.SONATYPE_PASSWORD" + } + } + maven { + name = 'staging' + url = "${rootProject.buildDir}/local-staging-repo" + } + } +} diff --git a/common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java b/common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java new file mode 100644 index 0000000000..7a2dc137a6 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java @@ -0,0 +1,298 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common; + +import java.io.IOException; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.InjectableValues; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; +import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +import org.opensearch.SpecialPermission; + +class ConfigMapSerializer extends StdSerializer> { + private static final Set SENSITIVE_CONFIG_KEYS = Set.of("password"); + + @SuppressWarnings("unchecked") + public ConfigMapSerializer() { + // Pass Map.class to the superclass + super((Class>) (Class) Map.class); + } + + @Override + public void serialize(Map value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + for (Map.Entry entry : value.entrySet()) { + if (SENSITIVE_CONFIG_KEYS.contains(entry.getKey())) { + gen.writeStringField(entry.getKey(), "******"); // Redact + } else { + gen.writeObjectField(entry.getKey(), entry.getValue()); + } + } + gen.writeEndObject(); + } +} + +public class DefaultObjectMapper { + public static final ObjectMapper objectMapper = new ObjectMapper(); + public final static ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory()); + private static final ObjectMapper defaulOmittingObjectMapper = new ObjectMapper(); + + static { + objectMapper.setSerializationInclusion(Include.NON_NULL); + // exclude sensitive information from the request body, + // if jackson cant parse the entity, e.g. passwords, hashes and so on, + // but provides which property is unknown + objectMapper.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); + defaulOmittingObjectMapper.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); + YAML_MAPPER.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); + // objectMapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS); + objectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); + defaulOmittingObjectMapper.setSerializationInclusion(Include.NON_DEFAULT); + defaulOmittingObjectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); + YAML_MAPPER.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); + } + + private DefaultObjectMapper() {} + + public static void inject(final InjectableValues.Std injectableValues) { + objectMapper.setInjectableValues(injectableValues); + YAML_MAPPER.setInjectableValues(injectableValues); + defaulOmittingObjectMapper.setInjectableValues(injectableValues); + } + + public static boolean getOrDefault(Map properties, String key, boolean defaultValue) throws JsonProcessingException { + Object value = properties.get(key); + if (value == null) { + return defaultValue; + } else if (value instanceof Boolean) { + return (boolean) value; + } else if (value instanceof String) { + String text = ((String) value).trim(); + if ("true".equals(text) || "True".equals(text)) { + return true; + } + if ("false".equals(text) || "False".equals(text)) { + return false; + } + throw InvalidFormatException.from( + null, + "Cannot deserialize value of type 'boolean' from String \"" + text + "\": only \"true\" or \"false\" recognized)", + null, + Boolean.class + ); + } + throw MismatchedInputException.from( + null, + Boolean.class, + "Cannot deserialize instance of 'boolean' out of '" + value + "' (Property: " + key + ")" + ); + } + + @SuppressWarnings("unchecked") + public static T getOrDefault(Map properties, String key, T defaultValue) { + T value = (T) properties.get(key); + return value != null ? value : defaultValue; + } + + @SuppressWarnings("removal") + public static T readTree(JsonNode node, Class clazz) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.treeToValue(node, clazz)); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + + @SuppressWarnings("removal") + public static T readValue(String string, Class clazz) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readValue(string, clazz)); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + + @SuppressWarnings("removal") + public static JsonNode readTree(String string) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readTree(string)); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + + @SuppressWarnings("removal") + public static String writeValueAsString(Object value, boolean omitDefaults) throws JsonProcessingException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> (omitDefaults ? defaulOmittingObjectMapper : objectMapper).writeValueAsString( + value + ) + ); + } catch (final PrivilegedActionException e) { + throw (JsonProcessingException) e.getCause(); + } + + } + + @SuppressWarnings("removal") + public static String writeValueAsStringAndRedactSensitive(Object value) throws JsonProcessingException { + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + SimpleModule module = new SimpleModule(); + module.addSerializer(new ConfigMapSerializer()); + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(module); + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> mapper.writeValueAsString(value)); + } catch (final PrivilegedActionException e) { + throw (JsonProcessingException) e.getCause(); + } + + } + + @SuppressWarnings("removal") + public static T readValue(String string, TypeReference tr) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public T run() throws Exception { + return objectMapper.readValue(string, tr); + } + }); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + + } + + @SuppressWarnings("removal") + public static T readValue(String string, JavaType jt) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readValue(string, jt)); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + + @SuppressWarnings("removal") + public static T convertValue(JsonNode jsonNode, JavaType jt) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.convertValue(jsonNode, jt)); + } catch (final PrivilegedActionException e) { + throw (IOException) e.getCause(); + } + } + + public static TypeFactory getTypeFactory() { + return objectMapper.getTypeFactory(); + } + + public static Set getFields(Class cls) { + return objectMapper.getSerializationConfig() + .introspect(getTypeFactory().constructType(cls)) + .findProperties() + .stream() + .map(BeanPropertyDefinition::getName) + .collect(ImmutableSet.toImmutableSet()); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/auditlog/impl/AuditCategory.java b/common/src/main/java/org/opensearch/security/common/auditlog/impl/AuditCategory.java new file mode 100644 index 0000000000..3526404bbd --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/auditlog/impl/AuditCategory.java @@ -0,0 +1,40 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.auditlog.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; + +public enum AuditCategory { + BAD_HEADERS, + FAILED_LOGIN, + MISSING_PRIVILEGES, + GRANTED_PRIVILEGES, + OPENDISTRO_SECURITY_INDEX_ATTEMPT, + SSL_EXCEPTION, + AUTHENTICATED, + INDEX_EVENT, + COMPLIANCE_DOC_READ, + COMPLIANCE_DOC_WRITE, + COMPLIANCE_EXTERNAL_CONFIG, + COMPLIANCE_INTERNAL_CONFIG_READ, + COMPLIANCE_INTERNAL_CONFIG_WRITE; + + public static Set parse(final Collection categories) { + if (categories.isEmpty()) return Collections.emptySet(); + + return categories.stream().map(String::toUpperCase).map(AuditCategory::valueOf).collect(ImmutableSet.toImmutableSet()); + } +} diff --git a/src/main/java/org/opensearch/security/auth/UserSubjectImpl.java b/common/src/main/java/org/opensearch/security/common/auth/UserSubjectImpl.java similarity index 83% rename from src/main/java/org/opensearch/security/auth/UserSubjectImpl.java rename to common/src/main/java/org/opensearch/security/common/auth/UserSubjectImpl.java index 63adc559e3..620250be53 100644 --- a/src/main/java/org/opensearch/security/auth/UserSubjectImpl.java +++ b/common/src/main/java/org/opensearch/security/common/auth/UserSubjectImpl.java @@ -7,7 +7,7 @@ * compatible open source license. * */ -package org.opensearch.security.auth; +package org.opensearch.security.common.auth; import java.security.Principal; import java.util.concurrent.Callable; @@ -16,8 +16,8 @@ import org.opensearch.identity.NamedPrincipal; import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.AuthToken; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.threadpool.ThreadPool; public class UserSubjectImpl implements UserSubject { @@ -25,7 +25,7 @@ public class UserSubjectImpl implements UserSubject { private final ThreadPool threadPool; private final User user; - UserSubjectImpl(ThreadPool threadPool, User user) { + public UserSubjectImpl(ThreadPool threadPool, User user) { this.threadPool = threadPool; this.user = user; this.userPrincipal = new NamedPrincipal(user.getName()); @@ -48,4 +48,8 @@ public T runAs(Callable callable) throws Exception { return callable.call(); } } + + public User getUser() { + return user; + } } diff --git a/common/src/main/java/org/opensearch/security/common/configuration/AdminDNs.java b/common/src/main/java/org/opensearch/security/common/configuration/AdminDNs.java new file mode 100644 index 0000000000..22647e6685 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/configuration/AdminDNs.java @@ -0,0 +1,162 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.configuration; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +import com.google.common.collect.ImmutableMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; + +public class AdminDNs { + + protected final Logger log = LogManager.getLogger(AdminDNs.class); + private final Set adminDn = new HashSet(); + private final Set adminUsernames = new HashSet(); + private final Map allowedDnsImpersonations; + private final Map allowedRestImpersonations; + private boolean injectUserEnabled; + private boolean injectAdminUserEnabled; + + public AdminDNs(final Settings settings) { + + this.injectUserEnabled = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false); + this.injectAdminUserEnabled = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, false); + + final List adminDnsA = settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Collections.emptyList()); + + for (String dn : adminDnsA) { + try { + log.debug("{} is registered as an admin dn", dn); + adminDn.add(new LdapName(dn)); + } catch (final InvalidNameException e) { + // make sure to log correctly depending on user injection settings + if (injectUserEnabled && injectAdminUserEnabled) { + if (log.isDebugEnabled()) { + log.debug("Admin DN not an LDAP name, but admin user injection enabled. Will add {} to admin usernames", dn); + } + adminUsernames.add(dn); + } else { + log.error("Unable to parse admin dn {}", dn, e); + } + } + } + + log.debug("Loaded {} admin DN's {}", adminDn.size(), adminDn); + + final Settings impersonationDns = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_IMPERSONATION_DN + "."); + + allowedDnsImpersonations = impersonationDns.keySet() + .stream() + .map(this::toLdapName) + .filter(Objects::nonNull) + .collect( + ImmutableMap.toImmutableMap( + Function.identity(), + ldapName -> WildcardMatcher.from(settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_IMPERSONATION_DN + "." + ldapName)) + ) + ); + + log.debug("Loaded {} impersonation DN's {}", allowedDnsImpersonations.size(), allowedDnsImpersonations); + + final Settings impersonationUsersRest = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + "."); + + allowedRestImpersonations = impersonationUsersRest.keySet() + .stream() + .collect( + ImmutableMap.toImmutableMap( + Function.identity(), + user -> WildcardMatcher.from(settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + "." + user)) + ) + ); + + log.debug("Loaded {} impersonation users for REST {}", allowedRestImpersonations.size(), allowedRestImpersonations); + } + + private LdapName toLdapName(String dn) { + try { + return new LdapName(dn); + } catch (final InvalidNameException e) { + log.error("Unable to parse allowedImpersonations dn {}", dn, e); + } + return null; + } + + public boolean isAdmin(User user) { + if (isAdminDN(user.getName())) { + return true; + } + + // ThreadContext injected user, may be admin user, only if both flags are enabled and user is injected + if (injectUserEnabled && injectAdminUserEnabled && user.isInjected() && adminUsernames.contains(user.getName())) { + return true; + } + return false; + } + + public boolean isAdminDN(String dn) { + + if (dn == null) return false; + + try { + return isAdminDN(new LdapName(dn)); + } catch (InvalidNameException e) { + return false; + } + } + + private boolean isAdminDN(LdapName dn) { + if (dn == null) return false; + + boolean isAdmin = adminDn.contains(dn); + + if (log.isTraceEnabled()) { + log.trace("Is principal {} an admin cert? {}", dn.toString(), isAdmin); + } + + return isAdmin; + } + + public boolean isRestImpersonationAllowed(final String originalUser, final String impersonated) { + return (originalUser != null) + ? allowedRestImpersonations.getOrDefault(originalUser, WildcardMatcher.NONE).test(impersonated) + : false; + } +} diff --git a/common/src/main/java/org/opensearch/security/common/dlic/rest/api/Responses.java b/common/src/main/java/org/opensearch/security/common/dlic/rest/api/Responses.java new file mode 100644 index 0000000000..e2258e9e6e --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/dlic/rest/api/Responses.java @@ -0,0 +1,106 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.dlic.rest.api; + +import java.io.IOException; + +import org.opensearch.ExceptionsHelper; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; + +public class Responses { + + public static void ok(final RestChannel channel, final String message) { + response(channel, RestStatus.OK, message); + } + + public static void ok(final RestChannel channel, final ToXContent toXContent) { + response(channel, RestStatus.OK, toXContent); + } + + public static void created(final RestChannel channel, final String message) { + response(channel, RestStatus.CREATED, message); + } + + public static void methodNotImplemented(final RestChannel channel, final RestRequest.Method method) { + notImplemented(channel, "Method " + method.name() + " not supported for this action."); + } + + public static void notImplemented(final RestChannel channel, final String message) { + response(channel, RestStatus.NOT_IMPLEMENTED, message); + } + + public static void notFound(final RestChannel channel, final String message) { + response(channel, RestStatus.NOT_FOUND, message); + } + + public static void conflict(final RestChannel channel, final String message) { + response(channel, RestStatus.CONFLICT, message); + } + + public static void internalServerError(final RestChannel channel, final String message) { + response(channel, RestStatus.INTERNAL_SERVER_ERROR, message); + } + + public static void forbidden(final RestChannel channel, final String message) { + response(channel, RestStatus.FORBIDDEN, message); + } + + public static void badRequest(final RestChannel channel, final String message) { + response(channel, RestStatus.BAD_REQUEST, message); + } + + public static void unauthorized(final RestChannel channel) { + response(channel, RestStatus.UNAUTHORIZED, "Unauthorized"); + } + + public static void response(RestChannel channel, RestStatus status, String message) { + response(channel, status, payload(status, message)); + } + + public static void response(final RestChannel channel, final RestStatus status, final ToXContent toXContent) { + try (final var builder = channel.newBuilder()) { + toXContent.toXContent(builder, ToXContent.EMPTY_PARAMS); + channel.sendResponse(new BytesRestResponse(status, builder)); + } catch (final IOException ioe) { + throw ExceptionsHelper.convertToOpenSearchException(ioe); + } + } + + public static ToXContent forbiddenMessage(final String message) { + return payload(RestStatus.FORBIDDEN, message); + } + + public static ToXContent badRequestMessage(final String message) { + return payload(RestStatus.BAD_REQUEST, message); + } + + public static ToXContent methodNotImplementedMessage(final RestRequest.Method method) { + return payload(RestStatus.NOT_FOUND, "Method " + method.name() + " not supported for this action."); + } + + public static ToXContent notFoundMessage(final String message) { + return payload(RestStatus.NOT_FOUND, message); + } + + public static ToXContent conflictMessage(final String message) { + return payload(RestStatus.CONFLICT, message); + } + + public static ToXContent payload(final RestStatus status, final String message) { + return (builder, params) -> builder.startObject().field("status", status.name()).field("message", message).endObject(); + } + +} diff --git a/common/src/main/java/org/opensearch/security/common/package-info.java b/common/src/main/java/org/opensearch/security/common/package-info.java new file mode 100644 index 0000000000..01e2ead134 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/package-info.java @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +/** + * This package defines common classes required to implement resource access control in OpenSearch. + * TODO: At present it contains multiple duplicates, which will be address in a fast follow PR. + * + * @opensearch.experimental + */ +package org.opensearch.security.common; diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceAccessHandler.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceAccessHandler.java new file mode 100644 index 0000000000..3912001aa1 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceAccessHandler.java @@ -0,0 +1,549 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.resources; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.action.StepListener; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.security.common.auth.UserSubjectImpl; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.ResourceParser; +import org.opensearch.security.spi.resources.exceptions.ResourceSharingException; +import org.opensearch.security.spi.resources.sharing.Recipient; +import org.opensearch.security.spi.resources.sharing.RecipientType; +import org.opensearch.security.spi.resources.sharing.RecipientTypeRegistry; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; +import org.opensearch.security.spi.resources.sharing.ShareWith; +import org.opensearch.security.spi.resources.sharing.SharedWithScope; +import org.opensearch.threadpool.ThreadPool; + +/** + * This class handles resource access permissions for users, roles and backend-roles. + * It provides methods to check if a user has permission to access a resource + * based on the resource sharing configuration. + * + * @opensearch.experimental + */ +public class ResourceAccessHandler { + private static final Logger LOGGER = LogManager.getLogger(ResourceAccessHandler.class); + + private final ThreadContext threadContext; + private final ResourceSharingIndexHandler resourceSharingIndexHandler; + private final AdminDNs adminDNs; + + public ResourceAccessHandler( + final ThreadPool threadPool, + final ResourceSharingIndexHandler resourceSharingIndexHandler, + AdminDNs adminDns + ) { + this.threadContext = threadPool.getThreadContext(); + this.resourceSharingIndexHandler = resourceSharingIndexHandler; + this.adminDNs = adminDns; + } + + /** + * Initializes the recipient types for users, roles, and backend roles. + * These recipient types are used to identify the types of recipients for resource sharing. + */ + public void initializeRecipientTypes() { + RecipientTypeRegistry.registerRecipientType(Recipient.USERS.getName(), new RecipientType(Recipient.USERS.getName())); + RecipientTypeRegistry.registerRecipientType(Recipient.ROLES.getName(), new RecipientType(Recipient.ROLES.getName())); + RecipientTypeRegistry.registerRecipientType( + Recipient.BACKEND_ROLES.getName(), + new RecipientType(Recipient.BACKEND_ROLES.getName()) + ); + } + + /** + * Returns a set of accessible resource IDs for the current user within the specified resource index. + * + * @param resourceIndex The resource index to check for accessible resources. + * @param listener The listener to be notified with the set of accessible resource IDs. + */ + public void getAccessibleResourceIdsForCurrentUser(String resourceIndex, ActionListener> listener) { + final UserSubjectImpl userSubject = (UserSubjectImpl) threadContext.getPersistent( + ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER + ); + final User user = (userSubject == null) ? null : userSubject.getUser(); + + // If no user is authenticated, return an empty set + if (user == null) { + LOGGER.warn("Unable to fetch user details. User is null."); + listener.onResponse(Collections.emptySet()); + return; + } + + LOGGER.debug("Listing accessible resources within the resource index {} for user: {}", resourceIndex, user.getName()); + + // 2. If the user is admin, simply fetch all resources + if (adminDNs.isAdmin(user)) { + loadAllResources(resourceIndex, ActionListener.wrap(listener::onResponse, listener::onFailure)); + return; + } + + // StepListener for the user’s "own" resources + StepListener> ownResourcesListener = new StepListener<>(); + + // StepListener for resources shared with the user’s name + StepListener> userNameResourcesListener = new StepListener<>(); + + // StepListener for resources shared with the user’s roles + StepListener> rolesResourcesListener = new StepListener<>(); + + // StepListener for resources shared with the user’s backend roles + StepListener> backendRolesResourcesListener = new StepListener<>(); + + // Load own resources for the user. + loadOwnResources(resourceIndex, user.getName(), ownResourcesListener); + + // Load resources shared with the user by its name. + ownResourcesListener.whenComplete( + ownResources -> loadSharedWithResources( + resourceIndex, + Set.of(user.getName()), + Recipient.USERS.getName(), + userNameResourcesListener + ), + listener::onFailure + ); + + // Load resources shared with the user’s roles. + userNameResourcesListener.whenComplete( + userNameResources -> loadSharedWithResources( + resourceIndex, + user.getSecurityRoles(), + Recipient.ROLES.getName(), + rolesResourcesListener + ), + listener::onFailure + ); + + // Load resources shared with the user’s backend roles. + rolesResourcesListener.whenComplete( + rolesResources -> loadSharedWithResources( + resourceIndex, + user.getRoles(), + Recipient.BACKEND_ROLES.getName(), + backendRolesResourcesListener + ), + listener::onFailure + ); + + // Combine all results and pass them back to the original listener. + backendRolesResourcesListener.whenComplete(backendRolesResources -> { + Set allResources = new HashSet<>(); + + // Retrieve results from each StepListener + allResources.addAll(ownResourcesListener.result()); + allResources.addAll(userNameResourcesListener.result()); + allResources.addAll(rolesResourcesListener.result()); + allResources.addAll(backendRolesResourcesListener.result()); + + LOGGER.debug("Found {} accessible resources for user {}", allResources.size(), user.getName()); + listener.onResponse(allResources); + }, listener::onFailure); + } + + /** + * Returns a set of accessible resources for the current user within the specified resource index. + * + * @param resourceIndex The resource index to check for accessible resources. + * @param listener The listener to be notified with the set of accessible resources. + */ + @SuppressWarnings("unchecked") + public void getAccessibleResourcesForCurrentUser(String resourceIndex, ActionListener> listener) { + try { + validateArguments(resourceIndex); + + ResourceParser parser = ResourcePluginInfo.getInstance().getResourceProviders().get(resourceIndex).resourceParser(); + + StepListener> resourceIdsListener = new StepListener<>(); + StepListener> resourcesListener = new StepListener<>(); + + // Fetch resource IDs + getAccessibleResourceIdsForCurrentUser(resourceIndex, resourceIdsListener); + + // Fetch docs + resourceIdsListener.whenComplete(resourceIds -> { + if (resourceIds.isEmpty()) { + // No accessible resources => immediately respond with empty set + listener.onResponse(Collections.emptySet()); + } else { + // Fetch the resource documents asynchronously + this.resourceSharingIndexHandler.getResourceDocumentsFromIds(resourceIds, resourceIndex, parser, resourcesListener); + } + }, listener::onFailure); + + // Send final response + resourcesListener.whenComplete( + listener::onResponse, + ex -> listener.onFailure(new ResourceSharingException("Failed to get accessible resources: " + ex.getMessage(), ex)) + ); + } catch (Exception e) { + LOGGER.warn("Failed to process accessible resources request: {}", e.getMessage()); + listener.onFailure(new ResourceSharingException("Failed to process accessible resources request: " + e.getMessage(), e)); + } + } + + /** + * Checks whether current user has given permission (scope) to access given resource. + * + * @param resourceId The resource ID to check access for. + * @param resourceIndex The resource index containing the resource. + * @param scopes The permission scope(s) to check. + * @param listener The listener to be notified with the permission check result. + */ + public void hasPermission(String resourceId, String resourceIndex, Set scopes, ActionListener listener) { + validateArguments(resourceId, resourceIndex, scopes); + + final UserSubjectImpl userSubject = (UserSubjectImpl) threadContext.getPersistent( + ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER + ); + final User user = (userSubject == null) ? null : userSubject.getUser(); + + if (user == null) { + LOGGER.warn("No authenticated user found. Access to resource {} is not authorized", resourceId); + listener.onResponse(false); + return; + } + + LOGGER.debug("Checking if user '{}' has '{}' permission to resource '{}'", user.getName(), scopes.toString(), resourceId); + + if (adminDNs.isAdmin(user)) { + LOGGER.debug( + "User '{}' is admin, automatically granted '{}' permission on '{}'", + user.getName(), + scopes.toString(), + resourceId + ); + listener.onResponse(true); + return; + } + + Set userRoles = new HashSet<>(user.getSecurityRoles()); + Set userBackendRoles = new HashSet<>(user.getRoles()); + + this.resourceSharingIndexHandler.fetchDocumentById(resourceIndex, resourceId, ActionListener.wrap(document -> { + if (document == null) { + LOGGER.warn("Resource '{}' not found in index '{}'", resourceId, resourceIndex); + listener.onFailure(new ResourceSharingException("Resource " + resourceId + " not found in index " + resourceIndex)); + return; + } + + // All public entities are designated with "*" + userRoles.add("*"); + userBackendRoles.add("*"); + if (isOwnerOfResource(document, user.getName()) + || isSharedWithEveryone(document) + || isSharedWithEntity(document, Recipient.USERS, Set.of(user.getName(), "*"), scopes) + || isSharedWithEntity(document, Recipient.ROLES, userRoles, scopes) + || isSharedWithEntity(document, Recipient.BACKEND_ROLES, userBackendRoles, scopes)) { + + LOGGER.debug("User '{}' has '{}' permission to resource '{}'", user.getName(), scopes.toString(), resourceId); + listener.onResponse(true); + } else { + LOGGER.debug("User '{}' does not have '{}' permission to resource '{}'", user.getName(), scopes.toString(), resourceId); + listener.onResponse(false); + } + }, exception -> { + LOGGER.error( + "Failed to fetch resource sharing document for resource '{}' in index '{}': {}", + resourceId, + resourceIndex, + exception.getMessage() + ); + listener.onFailure(exception); + })); + } + + /** + * Shares a resource with the specified users, roles, and backend roles. + * + * @param resourceId The resource ID to share. + * @param resourceIndex The index where resource is store + * @param shareWith The users, roles, and backend roles as well as scope to share the resource with. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + public void shareWith(String resourceId, String resourceIndex, ShareWith shareWith, ActionListener listener) { + validateArguments(resourceId, resourceIndex, shareWith); + + final UserSubjectImpl userSubject = (UserSubjectImpl) threadContext.getPersistent( + ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER + ); + final User user = (userSubject == null) ? null : userSubject.getUser(); + + if (user == null) { + LOGGER.warn("No authenticated user found. Failed to share resource {}", resourceId); + listener.onFailure(new ResourceSharingException("No authenticated user found. Failed to share resource " + resourceId)); + return; + } + + LOGGER.debug("Sharing resource {} created by {} with {}", resourceId, user.getName(), shareWith.toString()); + + boolean isAdmin = adminDNs.isAdmin(user); + + this.resourceSharingIndexHandler.updateResourceSharingInfo( + resourceId, + resourceIndex, + user.getName(), + shareWith, + isAdmin, + ActionListener.wrap(updatedResourceSharing -> { + LOGGER.debug("Successfully shared resource {} with {}", resourceId, shareWith.toString()); + listener.onResponse(updatedResourceSharing); + }, e -> { + LOGGER.error("Failed to share resource {} with {}: {}", resourceId, shareWith.toString(), e.getMessage()); + listener.onFailure(e); + }) + ); + } + + /** + * Revokes access to a resource for the specified users, roles, and backend roles. + * + * @param resourceId The resource ID to revoke access from. + * @param resourceIndex The index where resource is store + * @param revokeAccess The users, roles, and backend roles to revoke access for. + * @param scopes The permission scopes to revoke access for. + * @param listener The listener to be notified with the updated ResourceSharing document. + */ + public void revokeAccess( + String resourceId, + String resourceIndex, + Map> revokeAccess, + Set scopes, + ActionListener listener + ) { + validateArguments(resourceId, resourceIndex, revokeAccess, scopes); + + final UserSubjectImpl userSubject = (UserSubjectImpl) threadContext.getPersistent( + ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER + ); + final User user = (userSubject == null) ? null : userSubject.getUser(); + + if (user == null) { + LOGGER.warn("No authenticated user found. Failed to revoker access to resource {}", resourceId); + listener.onFailure( + new ResourceSharingException("No authenticated user found. Failed to revoke access to resource {}" + resourceId) + ); + return; + } + + LOGGER.debug("User {} revoking access to resource {} for {} for scopes {}.", user.getName(), resourceId, revokeAccess, scopes); + + boolean isAdmin = adminDNs.isAdmin(user); + + this.resourceSharingIndexHandler.revokeAccess( + resourceId, + resourceIndex, + revokeAccess, + scopes, + user.getName(), + isAdmin, + ActionListener.wrap(listener::onResponse, exception -> { + LOGGER.error("Failed to revoke access to resource {} in index {}: {}", resourceId, resourceIndex, exception.getMessage()); + listener.onFailure(exception); + }) + ); + } + + /** + * Deletes a resource sharing record by its ID and the resource index it belongs to. + * + * @param resourceId The resource ID to delete. + * @param resourceIndex The resource index containing the resource. + * @param listener The listener to be notified with the deletion result. + */ + public void deleteResourceSharingRecord(String resourceId, String resourceIndex, ActionListener listener) { + try { + validateArguments(resourceId, resourceIndex); + + LOGGER.debug("Deleting resource sharing record for resource {} in {}", resourceId, resourceIndex); + + StepListener deleteDocListener = new StepListener<>(); + resourceSharingIndexHandler.deleteResourceSharingRecord(resourceId, resourceIndex, deleteDocListener); + deleteDocListener.whenComplete(listener::onResponse, listener::onFailure); + + } catch (Exception e) { + LOGGER.error("Failed to delete resource sharing record for resource {}", resourceId, e); + listener.onFailure(e); + } + } + + /** + * Deletes all resource sharing records for the current user. + * + * @param listener The listener to be notified with the deletion result. + */ + public void deleteAllResourceSharingRecordsForCurrentUser(ActionListener listener) { + final UserSubjectImpl userSubject = (UserSubjectImpl) threadContext.getPersistent( + ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER + ); + final User user = (userSubject == null) ? null : userSubject.getUser(); + + if (user == null) { + listener.onFailure(new ResourceSharingException("No authenticated user available.")); + return; + } + + LOGGER.debug("Deleting all resource sharing records for user {}", user.getName()); + + resourceSharingIndexHandler.deleteAllRecordsForUser(user.getName(), ActionListener.wrap(listener::onResponse, exception -> { + LOGGER.error( + "Failed to delete all resource sharing records for user {}: {}", + user.getName(), + exception.getMessage(), + exception + ); + listener.onFailure(exception); + })); + } + + /** + * Loads all resources within the specified resource index. + * + * @param resourceIndex The resource index to load resources from. + * @param listener The listener to be notified with the set of resource IDs. + */ + private void loadAllResources(String resourceIndex, ActionListener> listener) { + this.resourceSharingIndexHandler.fetchAllDocuments(resourceIndex, listener); + } + + /** + * Loads resources owned by the specified user within the given resource index. + * + * @param resourceIndex The resource index to load resources from. + * @param userName The username of the owner. + * @param listener The listener to be notified with the set of resource IDs. + */ + private void loadOwnResources(String resourceIndex, String userName, ActionListener> listener) { + this.resourceSharingIndexHandler.fetchDocumentsByField(resourceIndex, "created_by.user", userName, listener); + } + + /** + * Loads resources shared with the specified entities within the given resource index, including public resources. + * + * @param resourceIndex The resource index to load resources from. + * @param entities The set of entities to check for shared resources. + * @param recipientType The type of entity (e.g., users, roles, backend_roles). + * @param listener The listener to be notified with the set of resource IDs. + */ + private void loadSharedWithResources( + String resourceIndex, + Set entities, + String recipientType, + ActionListener> listener + ) { + Set entitiesCopy = new HashSet<>(entities); + // To allow "public" resources to be matched for any user, role, backend_role + entitiesCopy.add("*"); + this.resourceSharingIndexHandler.fetchDocumentsForAllScopes(resourceIndex, entitiesCopy, recipientType, listener); + } + + /** + * Checks if the given resource is owned by the specified user. + * + * @param document The ResourceSharing document to check. + * @param userName The username to check ownership against. + * @return True if the resource is owned by the user, false otherwise. + */ + private boolean isOwnerOfResource(ResourceSharing document, String userName) { + return document.getCreatedBy() != null && document.getCreatedBy().getCreator().equals(userName); + } + + /** + * Checks if the given resource is shared with the specified entities and scope. + * + * @param document The ResourceSharing document to check. + * @param recipient The recipient entity + * @param entities The set of entities to check for sharing. + * @param scopes The permission scope(s) to check. + * @return True if the resource is shared with the entities and scope, false otherwise. + */ + private boolean isSharedWithEntity(ResourceSharing document, Recipient recipient, Set entities, Set scopes) { + for (String entity : entities) { + if (checkSharing(document, recipient, entity, scopes)) { + return true; + } + } + return false; + } + + /** + * Checks if the given resource is shared with everyone, i.e. the scope is named "*" + * + * @param document The ResourceSharing document to check. + * @return True if the resource is shared with everyone, false otherwise. + */ + private boolean isSharedWithEveryone(ResourceSharing document) { + return document.getShareWith() != null + && document.getShareWith().getSharedWithScopes().stream().anyMatch(sharedWithScope -> sharedWithScope.getScope().equals("*")); + } + + /** + * Checks if the given resource is shared with the specified entity and scope. + * + * @param document The ResourceSharing document to check. + * @param recipient The recipient entity + * @param entity The entity to check for sharing. + * @param scopes The permission scope(s) to check. + * @return True if the resource is shared with the entity and scope, false otherwise. + */ + private boolean checkSharing(ResourceSharing document, Recipient recipient, String entity, Set scopes) { + if (document.getShareWith() == null) { + return false; + } + + return document.getShareWith() + .getSharedWithScopes() + .stream() + .filter(sharedWithScope -> scopes.contains(sharedWithScope.getScope())) + .findFirst() + .map(sharedWithScope -> { + SharedWithScope.ScopeRecipients scopePermissions = sharedWithScope.getSharedWithPerScope(); + Map> recipients = scopePermissions.getRecipients(); + + return switch (recipient) { + case Recipient.USERS, Recipient.ROLES, Recipient.BACKEND_ROLES -> recipients.get( + RecipientTypeRegistry.fromValue(recipient.getName()) + ).contains(entity); + }; + }) + .orElse(false); // Return false if no matching scope is found + } + + private void validateArguments(Object... args) { + if (args == null) { + throw new IllegalArgumentException("Arguments cannot be null"); + } + for (Object arg : args) { + if (arg == null) { + throw new IllegalArgumentException("Argument cannot be null"); + } + // Additional check for String type arguments + if (arg instanceof String && ((String) arg).trim().isEmpty()) { + throw new IllegalArgumentException("Arguments cannot be empty"); + } + } + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceIndexListener.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceIndexListener.java new file mode 100644 index 0000000000..4b502096b4 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceIndexListener.java @@ -0,0 +1,123 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources; + +import java.io.IOException; +import java.util.Objects; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.index.shard.ShardId; +import org.opensearch.index.engine.Engine; +import org.opensearch.index.shard.IndexingOperationListener; +import org.opensearch.security.common.auth.UserSubjectImpl; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; +import org.opensearch.security.spi.resources.sharing.CreatedBy; +import org.opensearch.security.spi.resources.sharing.Creator; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.client.Client; + +/** + * This class implements an index operation listener for operations performed on resources stored in plugin's indices. + * + * @opensearch.experimental + */ +public class ResourceIndexListener implements IndexingOperationListener { + + private static final Logger log = LogManager.getLogger(ResourceIndexListener.class); + private static final ResourceIndexListener INSTANCE = new ResourceIndexListener(); + private ResourceSharingIndexHandler resourceSharingIndexHandler; + + private boolean initialized; + private ThreadPool threadPool; + + private ResourceIndexListener() {} + + public static ResourceIndexListener getInstance() { + return ResourceIndexListener.INSTANCE; + } + + public void initialize(ThreadPool threadPool, Client client) { + if (initialized) { + return; + } + initialized = true; + this.threadPool = threadPool; + this.resourceSharingIndexHandler = new ResourceSharingIndexHandler( + ResourceSharingConstants.OPENSEARCH_RESOURCE_SHARING_INDEX, + client, + threadPool + ); + } + + public boolean isInitialized() { + return initialized; + } + + /** + * Creates a resource sharing entry for the newly created resource. + */ + @Override + public void postIndex(ShardId shardId, Engine.Index index, Engine.IndexResult result) { + String resourceIndex = shardId.getIndexName(); + log.debug("postIndex called on {}", resourceIndex); + + String resourceId = index.id(); + + // Only proceed if this was a create operation + if (!result.isCreated()) { + log.debug("Skipping resource sharing entry creation as this was an update operation for resource {}", resourceId); + return; + } + + final UserSubjectImpl userSubject = (UserSubjectImpl) threadPool.getThreadContext() + .getPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER); + final User user = userSubject.getUser(); + + try { + Objects.requireNonNull(user); + ResourceSharing sharing = this.resourceSharingIndexHandler.indexResourceSharing( + resourceId, + resourceIndex, + new CreatedBy(Creator.USER, user.getName()), + null + ); + log.debug( + "Successfully created a resource sharing entry {} for resource {} within index {}", + sharing, + resourceId, + resourceIndex + ); + } catch (IOException e) { + log.debug("Failed to create a resource sharing entry for resource: {}", resourceId, e); + } + } + + /** + * Deletes the resource sharing entry for the deleted resource. + */ + @Override + public void postDelete(ShardId shardId, Engine.Delete delete, Engine.DeleteResult result) { + String resourceIndex = shardId.getIndexName(); + log.debug("postDelete called on {}", resourceIndex); + + String resourceId = delete.id(); + this.resourceSharingIndexHandler.deleteResourceSharingRecord(resourceId, resourceIndex, ActionListener.wrap(deleted -> { + if (deleted) { + log.debug("Successfully deleted resource sharing entry for resource {}", resourceId); + } else { + log.debug("No resource sharing entry found for resource {}", resourceId); + } + }, exception -> log.error("Failed to delete resource sharing entry for resource {}", resourceId, exception))); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourcePluginInfo.java b/common/src/main/java/org/opensearch/security/common/resources/ResourcePluginInfo.java new file mode 100644 index 0000000000..fde006c198 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourcePluginInfo.java @@ -0,0 +1,58 @@ +package org.opensearch.security.common.resources; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * This class provides information about resource plugins and their associated resource providers and indices. + * It follows the Singleton pattern to ensure that only one instance of the class exists. + * + * @opensearch.experimental + */ +public class ResourcePluginInfo { + private static ResourcePluginInfo INSTANCE; + + private final Map resourceProviderMap = new HashMap<>(); + private final Set resourceIndices = new HashSet<>(); + + private ResourcePluginInfo() {} + + public static ResourcePluginInfo getInstance() { + if (INSTANCE == null) { + INSTANCE = new ResourcePluginInfo(); + } + return INSTANCE; + } + + public void setResourceProviders(Map providerMap) { + resourceProviderMap.clear(); + resourceProviderMap.putAll(providerMap); + } + + public void setResourceIndices(Set indices) { + resourceIndices.clear(); + resourceIndices.addAll(indices); + } + + public Map getResourceProviders() { + return ImmutableMap.copyOf(resourceProviderMap); + } + + public Set getResourceIndices() { + return ImmutableSet.copyOf(resourceIndices); + } + + // TODO following should be removed once core test framework allows loading extended classes + public Map getResourceProvidersMutable() { + return resourceProviderMap; + } + + public Set getResourceIndicesMutable() { + return resourceIndices; + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceProvider.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceProvider.java new file mode 100644 index 0000000000..b2537fc849 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceProvider.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources; + +import org.opensearch.security.spi.resources.ResourceParser; + +/** + * This record class represents a resource provider. + * It holds information about the resource type, resource index name, and a resource parser. + * + * @opensearch.experimental + */ +public record ResourceProvider(String resourceType, String resourceIndexName, ResourceParser resourceParser) { + +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingConstants.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingConstants.java new file mode 100644 index 0000000000..a1004566e5 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingConstants.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ +package org.opensearch.security.common.resources; + +/** + * This class contains constants related to resource sharing in OpenSearch. + * + * @opensearch.experimental + */ +public class ResourceSharingConstants { + // Resource sharing index + public static final String OPENSEARCH_RESOURCE_SHARING_INDEX = ".opensearch_resource_sharing"; +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java new file mode 100644 index 0000000000..8ff771d74e --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java @@ -0,0 +1,1402 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + */ +package org.opensearch.security.common.resources; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; + +import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.action.DocWriteRequest; +import org.opensearch.action.StepListener; +import org.opensearch.action.admin.indices.create.CreateIndexRequest; +import org.opensearch.action.admin.indices.create.CreateIndexResponse; +import org.opensearch.action.get.MultiGetItemResponse; +import org.opensearch.action.get.MultiGetRequest; +import org.opensearch.action.index.IndexRequest; +import org.opensearch.action.index.IndexResponse; +import org.opensearch.action.search.ClearScrollRequest; +import org.opensearch.action.search.SearchRequest; +import org.opensearch.action.search.SearchResponse; +import org.opensearch.action.search.SearchScrollRequest; +import org.opensearch.action.support.WriteRequest; +import org.opensearch.common.unit.TimeValue; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.common.xcontent.XContentHelper; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.common.bytes.BytesReference; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.index.IndexNotFoundException; +import org.opensearch.index.query.BoolQueryBuilder; +import org.opensearch.index.query.MultiMatchQueryBuilder; +import org.opensearch.index.query.QueryBuilders; +import org.opensearch.index.reindex.BulkByScrollResponse; +import org.opensearch.index.reindex.DeleteByQueryAction; +import org.opensearch.index.reindex.DeleteByQueryRequest; +import org.opensearch.index.reindex.UpdateByQueryAction; +import org.opensearch.index.reindex.UpdateByQueryRequest; +import org.opensearch.script.Script; +import org.opensearch.script.ScriptType; +import org.opensearch.search.Scroll; +import org.opensearch.search.SearchHit; +import org.opensearch.search.builder.SearchSourceBuilder; +import org.opensearch.security.common.DefaultObjectMapper; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.ResourceParser; +import org.opensearch.security.spi.resources.exceptions.ResourceSharingException; +import org.opensearch.security.spi.resources.sharing.CreatedBy; +import org.opensearch.security.spi.resources.sharing.RecipientType; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; +import org.opensearch.security.spi.resources.sharing.ShareWith; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.transport.client.Client; + +import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; + +/** + * This class handles the creation and management of the resource sharing index. + * It provides methods to create the index, index resource sharing entries along with updates and deletion, retrieve shared resources. + * + * @opensearch.experimental + */ +public class ResourceSharingIndexHandler { + + private static final Logger LOGGER = LogManager.getLogger(ResourceSharingIndexHandler.class); + + private final Client client; + + private final String resourceSharingIndex; + + private final ThreadPool threadPool; + + public ResourceSharingIndexHandler(final String indexName, final Client client, final ThreadPool threadPool) { + this.resourceSharingIndex = indexName; + this.client = client; + this.threadPool = threadPool; + } + + public final static Map INDEX_SETTINGS = Map.of( + "index.number_of_shards", + 1, + "index.auto_expand_replicas", + "0-all", + "index.hidden", + "true" + ); + + /** + * Creates the resource sharing index if it doesn't already exist. + * This method initializes the index with predefined mappings and settings + * for storing resource sharing information. + * The index will be created with the following structure: + * - source_idx (keyword): The source index containing the original document + * - resource_id (keyword): The ID of the shared resource + * - created_by (object): Information about the user who created the sharing + * - user (keyword): Username of the creator + * - share_with (object): Access control configuration for shared resources + * - [scope] (object): Name of the scope + * - users (array): List of users with access + * - roles (array): List of roles with access + * - backend_roles (array): List of backend roles with access + * + * @throws RuntimeException if there are issues reading/writing index settings + * or communicating with the cluster + */ + + public void createResourceSharingIndexIfAbsent(Callable callable) { + // TODO: Once stashContext is replaced with switchContext this call will have to be modified + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + + CreateIndexRequest cir = new CreateIndexRequest(resourceSharingIndex).settings(INDEX_SETTINGS).waitForActiveShards(1); + ActionListener cirListener = ActionListener.wrap(response -> { + LOGGER.info("Resource sharing index {} created.", resourceSharingIndex); + if (callable != null) { + callable.call(); + } + }, (failResponse) -> { + /* Index already exists, ignore and continue */ + LOGGER.info("Index {} already exists.", resourceSharingIndex); + try { + if (callable != null) { + callable.call(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + this.client.admin().indices().create(cir, cirListener); + } + } + + /** + * Creates or updates a resource sharing record in the dedicated resource sharing index. + * This method handles the persistence of sharing metadata for resources, including + * the creator information and sharing permissions. + * + * @param resourceId The unique identifier of the resource being shared + * @param resourceIndex The source index where the original resource is stored + * @param createdBy Object containing information about the user creating/updating the sharing + * @param shareWith Object containing the sharing permissions' configuration. Can be null for initial creation. + * When provided, it should contain the access control settings for different groups: + * { + * "scope": { + * "users": ["user1", "user2"], + * "roles": ["role1", "role2"], + * "backend_roles": ["backend_role1"] + * } + * } + * @return ResourceSharing Returns resourceSharing object if the operation was successful, null otherwise + * @throws IOException if there are issues with index operations or JSON processing + */ + public ResourceSharing indexResourceSharing(String resourceId, String resourceIndex, CreatedBy createdBy, ShareWith shareWith) + throws IOException { + // TODO: Once stashContext is replaced with switchContext this call will have to be modified + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + ResourceSharing entry = new ResourceSharing(resourceIndex, resourceId, createdBy, shareWith); + + IndexRequest ir = client.prepareIndex(resourceSharingIndex) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .setSource(entry.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) + .setOpType(DocWriteRequest.OpType.CREATE) // only create if an entry doesn't exist + .request(); + + ActionListener irListener = ActionListener.wrap( + idxResponse -> LOGGER.info( + "Successfully created {} entry for resource {} in index {}.", + resourceSharingIndex, + resourceId, + resourceIndex + ), + (failResponse) -> { + LOGGER.error(failResponse.getMessage()); + } + ); + client.index(ir, irListener); + return entry; + } catch (Exception e) { + LOGGER.error("Failed to create {} entry.", resourceSharingIndex, e); + throw new ResourceSharingException("Failed to create " + resourceSharingIndex + " entry.", e); + } + } + + /** + * Fetches all resource sharing records that match the specified system index. This method retrieves + * a get of resource IDs associated with the given system index from the resource sharing index. + * + *

The method executes the following steps: + *

    + *
  1. Creates a search request with term query matching the system index
  2. + *
  3. Applies source filtering to only fetch resource_id field
  4. + *
  5. Executes the search with a limit of 10000 documents
  6. + *
  7. Processes the results to extract resource IDs
  8. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "term": {
+     *       "source_idx": "resource_index_name"
+     *     }
+     *   },
+     *   "_source": ["resource_id"],
+     *   "size": 10000
+     * }
+     * 
+ * + * @param pluginIndex The source index to match against the source_idx field + * @param listener The listener to be notified when the operation completes. + * The listener receives a set of resource IDs as a result. + * @apiNote This method: + *
    + *
  • Uses source filtering for optimal performance
  • + *
  • Performs exact matching on the source_idx field
  • + *
  • Returns an empty get instead of throwing exceptions
  • + *
+ */ + public void fetchAllDocuments(String pluginIndex, ActionListener> listener) { + LOGGER.debug("Fetching all documents asynchronously from {} where source_idx = {}", resourceSharingIndex, pluginIndex); + + try (final ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + SearchRequest searchRequest = new SearchRequest(resourceSharingIndex); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query( + QueryBuilders.termQuery("source_idx.keyword", pluginIndex) + ).size(10000).fetchSource(new String[] { "resource_id" }, null); + + searchRequest.source(searchSourceBuilder); + + client.search(searchRequest, new ActionListener<>() { + @Override + public void onResponse(SearchResponse searchResponse) { + try { + Set resourceIds = new HashSet<>(); + + SearchHit[] hits = searchResponse.getHits().getHits(); + for (SearchHit hit : hits) { + Map sourceAsMap = hit.getSourceAsMap(); + if (sourceAsMap != null && sourceAsMap.containsKey("resource_id")) { + resourceIds.add(sourceAsMap.get("resource_id").toString()); + } + } + + LOGGER.debug("Found {} documents in {} for source_idx: {}", resourceIds.size(), resourceSharingIndex, pluginIndex); + + listener.onResponse(resourceIds); + } catch (Exception e) { + LOGGER.error( + "Error while processing search response from {} for source_idx: {}", + resourceSharingIndex, + pluginIndex, + e + ); + listener.onFailure(e); + } + } + + @Override + public void onFailure(Exception e) { + LOGGER.error("Failed to fetch documents from {} for source_idx: {}", resourceSharingIndex, pluginIndex, e); + listener.onFailure(e); + } + }); + } catch (Exception e) { + LOGGER.error("Failed to initiate fetch documents from {} for source_idx: {}", resourceSharingIndex, pluginIndex, e); + listener.onFailure(e); + } + } + + /** + * Fetches documents that match the specified system index and have specific access type values. + * This method uses scroll API to handle large result sets efficiently. + * + *

The method executes the following steps: + *

    + *
  1. Validates the RecipientType parameter
  2. + *
  3. Creates a scrolling search request with a compound query
  4. + *
  5. Processes results in batches using scroll API
  6. + *
  7. Collects all matching resource IDs
  8. + *
  9. Cleans up scroll context
  10. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx": "resource_index_name" } },
+     *         {
+     *           "bool": {
+     *             "should": [
+     *               {
+     *                 "nested": {
+     *                   "path": "share_with.*.RecipientType",
+     *                   "query": {
+     *                     "term": { "share_with.*.RecipientType": "entity_value" }
+     *                   }
+     *                 }
+     *               }
+     *             ],
+     *             "minimum_should_match": 1
+     *           }
+     *         }
+     *       ]
+     *     }
+     *   },
+     *   "_source": ["resource_id"],
+     *   "size": 1000
+     * }
+     * 
+ * + * @param pluginIndex The source index to match against the source_idx field + * @param entities Set of values to match in the specified RecipientType field + * @param recipientType The type of association with the resource. Must be one of: + *
    + *
  • "users" - for user-based access
  • + *
  • "roles" - for role-based access
  • + *
  • "backend_roles" - for backend role-based access
  • + *
+ * @param listener The listener to be notified when the operation completes. + * The listener receives a set of resource IDs as a result. + * @throws RuntimeException if the search operation fails + * @apiNote This method: + *
    + *
  • Uses scroll API with 1-minute timeout
  • + *
  • Processes results in batches of 1000 documents
  • + *
  • Performs source filtering for optimization
  • + *
  • Uses nested queries for accessing array elements
  • + *
  • Properly cleans up scroll context after use
  • + *
+ */ + + public void fetchDocumentsForAllScopes( + String pluginIndex, + Set entities, + String recipientType, + ActionListener> listener + ) { + // "*" must match all scopes + fetchDocumentsForAGivenScope(pluginIndex, entities, recipientType, "*", listener); + } + + /** + * Fetches documents that match the specified system index and have specific access type values for a given scope. + * This method uses scroll API to handle large result sets efficiently. + * + *

The method executes the following steps: + *

    + *
  1. Validates the RecipientType parameter
  2. + *
  3. Creates a scrolling search request with a compound query
  4. + *
  5. Processes results in batches using scroll API
  6. + *
  7. Collects all matching resource IDs
  8. + *
  9. Cleans up scroll context
  10. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx": "resource_index_name" } },
+     *         {
+     *           "bool": {
+     *             "should": [
+     *               {
+     *                 "nested": {
+     *                   "path": "share_with.scope.RecipientType",
+     *                   "query": {
+     *                     "term": { "share_with.scope.RecipientType": "entity_value" }
+     *                   }
+     *                 }
+     *               }
+     *             ],
+     *             "minimum_should_match": 1
+     *           }
+     *         }
+     *       ]
+     *     }
+     *   },
+     *   "_source": ["resource_id"],
+     *   "size": 1000
+     * }
+     * 
+ * + * @param pluginIndex The source index to match against the source_idx field + * @param entities Set of values to match in the specified RecipientType field + * @param recipientType The type of association with the resource. Must be one of: + *
    + *
  • "users" - for user-based access
  • + *
  • "roles" - for role-based access
  • + *
  • "backend_roles" - for backend role-based access
  • + *
+ * @param scope The scope of the access. Should be implementation of {@link org.opensearch.security.spi.resources.ResourceAccessScope} + * @param listener The listener to be notified when the operation completes. + * The listener receives a set of resource IDs as a result. + * @throws RuntimeException if the search operation fails + * @apiNote This method: + *
    + *
  • Uses scroll API with 1-minute timeout
  • + *
  • Processes results in batches of 1000 documents
  • + *
  • Performs source filtering for optimization
  • + *
  • Uses nested queries for accessing array elements
  • + *
  • Properly cleans up scroll context after use
  • + *
+ */ + public void fetchDocumentsForAGivenScope( + String pluginIndex, + Set entities, + String recipientType, + String scope, + ActionListener> listener + ) { + LOGGER.debug( + "Fetching documents asynchronously from index: {}, where share_with.{}.{} contains any of {}", + pluginIndex, + scope, + recipientType, + entities + ); + + final Set resourceIds = new HashSet<>(); + final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); + + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + SearchRequest searchRequest = new SearchRequest(resourceSharingIndex); + searchRequest.scroll(scroll); + + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("source_idx.keyword", pluginIndex)); + + BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery(); + if ("*".equals(scope)) { + for (String entity : entities) { + shouldQuery.should( + QueryBuilders.multiMatchQuery(entity, "share_with.*." + recipientType + ".keyword") + .type(MultiMatchQueryBuilder.Type.BEST_FIELDS) + ); + } + } else { + for (String entity : entities) { + shouldQuery.should(QueryBuilders.termQuery("share_with." + scope + "." + recipientType + ".keyword", entity)); + } + } + shouldQuery.minimumShouldMatch(1); + + boolQuery.must(QueryBuilders.existsQuery("share_with")).must(shouldQuery); + + executeSearchRequest(resourceIds, scroll, searchRequest, boolQuery, ActionListener.wrap(success -> { + LOGGER.debug("Found {} documents matching the criteria in {}", resourceIds.size(), resourceSharingIndex); + listener.onResponse(resourceIds); + + }, exception -> { + LOGGER.error( + "Search failed for pluginIndex={}, scope={}, recipientType={}, entities={}", + pluginIndex, + scope, + recipientType, + entities, + exception + ); + listener.onFailure(exception); + + })); + } catch (Exception e) { + LOGGER.error( + "Failed to initiate fetch from {} for criteria - pluginIndex: {}, scope: {}, RecipientType: {}, entities: {}", + resourceSharingIndex, + pluginIndex, + scope, + recipientType, + entities, + e + ); + listener.onFailure(new RuntimeException("Failed to fetch documents: " + e.getMessage(), e)); + } + } + + /** + * Fetches documents from the resource sharing index that match a specific field value. + * This method uses scroll API to efficiently handle large result sets and performs exact + * matching on both system index and the specified field. + * + *

The method executes the following steps: + *

    + *
  1. Validates input parameters for null/empty values
  2. + *
  3. Creates a scrolling search request with a bool query
  4. + *
  5. Processes results in batches using scroll API
  6. + *
  7. Extracts resource IDs from matching documents
  8. + *
  9. Cleans up scroll context after completion
  10. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx": "system_index_value" } },
+     *         { "term": { "field_name": "field_value" } }
+     *       ]
+     *     }
+     *   },
+     *   "_source": ["resource_id"],
+     *   "size": 1000
+     * }
+     * 
+ * + * @param pluginIndex The source index to match against the source_idx field + * @param field The field name to search in. Must be a valid field in the index mapping + * @param value The value to match for the specified field. Performs exact term matching + * @param listener The listener to be notified when the operation completes. + * The listener receives a set of resource IDs as a result. + * @throws IllegalArgumentException if any parameter is null or empty + * @throws RuntimeException if the search operation fails, wrapping the underlying exception + * @apiNote This method: + *
    + *
  • Uses scroll API with 1-minute timeout for handling large result sets
  • + *
  • Performs exact term matching (not analyzed) on field values
  • + *
  • Processes results in batches of 1000 documents
  • + *
  • Uses source filtering to only fetch resource_id field
  • + *
  • Automatically cleans up scroll context after use
  • + *
+ *

+ * Example usage: + *

+     * Set resources = fetchDocumentsByField("myIndex", "status", "active");
+     * 
+ */ + public void fetchDocumentsByField(String pluginIndex, String field, String value, ActionListener> listener) { + if (StringUtils.isBlank(pluginIndex) || StringUtils.isBlank(field) || StringUtils.isBlank(value)) { + listener.onFailure(new IllegalArgumentException("pluginIndex, field, and value must not be null or empty")); + return; + } + + LOGGER.debug("Fetching documents from index: {}, where {} = {}", pluginIndex, field, value); + + Set resourceIds = new HashSet<>(); + final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); + + // TODO: Once stashContext is replaced with switchContext this call will have to be modified + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + SearchRequest searchRequest = new SearchRequest(resourceSharingIndex); + searchRequest.scroll(scroll); + + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("source_idx.keyword", pluginIndex)) + .must(QueryBuilders.termQuery(field + ".keyword", value)); + + executeSearchRequest(resourceIds, scroll, searchRequest, boolQuery, ActionListener.wrap(success -> { + LOGGER.debug("Found {} documents in {} where {} = {}", resourceIds.size(), resourceSharingIndex, field, value); + listener.onResponse(resourceIds); + }, exception -> { + LOGGER.error("Failed to fetch documents from {} where {} = {}", resourceSharingIndex, field, value, exception); + listener.onFailure(new RuntimeException("Failed to fetch documents: " + exception.getMessage(), exception)); + })); + } catch (Exception e) { + LOGGER.error("Failed to initiate fetch from {} where {} = {}", resourceSharingIndex, field, value, e); + listener.onFailure(new RuntimeException("Failed to initiate fetch: " + e.getMessage(), e)); + } + + } + + /** + * Fetches a specific resource sharing document by its resource ID and system index. + * This method performs an exact match search and parses the result into a ResourceSharing object. + * + *

The method executes the following steps: + *

    + *
  1. Validates input parameters for null/empty values
  2. + *
  3. Creates a search request with a bool query for exact matching
  4. + *
  5. Executes the search with a limit of 1 document
  6. + *
  7. Parses the result using XContent parser if found
  8. + *
  9. Returns null if no matching document exists
  10. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx": "resource_index_name" } },
+     *         { "term": { "resource_id": "resource_id_value" } }
+     *       ]
+     *     }
+     *   },
+     *   "size": 1
+     * }
+     * 
+ * + * @param pluginIndex The source index to match against the source_idx field + * @param resourceId The resource ID to fetch. Must exactly match the resource_id field + * @param listener The listener to be notified when the operation completes. + * The listener receives the parsed ResourceSharing object or null if not found + * @throws IllegalArgumentException if pluginIndexName or resourceId is null or empty + * @throws RuntimeException if the search operation fails or parsing errors occur, + * wrapping the underlying exception + * @apiNote This method: + *
    + *
  • Uses term queries for exact matching
  • + *
  • Expects only one matching document per resource ID
  • + *
  • Uses XContent parsing for consistent object creation
  • + *
  • Returns null instead of throwing exceptions for non-existent documents
  • + *
  • Provides detailed logging for troubleshooting
  • + *
+ *

+ * Example usage: + *

+     * ResourceSharing sharing = fetchDocumentById("myIndex", "resource123");
+     * if (sharing != null) {
+     *     // Process the resource sharing object
+     * }
+     * 
+ */ + public void fetchDocumentById(String pluginIndex, String resourceId, ActionListener listener) { + if (StringUtils.isBlank(pluginIndex) || StringUtils.isBlank(resourceId)) { + listener.onFailure(new IllegalArgumentException("pluginIndex and resourceId must not be null or empty")); + return; + } + LOGGER.debug("Fetching document from index: {}, resourceId: {}", pluginIndex, resourceId); + + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("source_idx.keyword", pluginIndex)) + .must(QueryBuilders.termQuery("resource_id.keyword", resourceId)); + + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(boolQuery).size(1); // There is only one document for + // a single resource + + SearchRequest searchRequest = new SearchRequest(resourceSharingIndex).source(searchSourceBuilder); + + client.search(searchRequest, new ActionListener<>() { + @Override + public void onResponse(SearchResponse searchResponse) { + try { + SearchHit[] hits = searchResponse.getHits().getHits(); + if (hits.length == 0) { + LOGGER.debug("No document found for resourceId: {} in index: {}", resourceId, pluginIndex); + listener.onResponse(null); + return; + } + + SearchHit hit = hits[0]; + try ( + XContentParser parser = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, hit.getSourceAsString()) + ) { + parser.nextToken(); + ResourceSharing resourceSharing = ResourceSharing.fromXContent(parser); + + LOGGER.debug("Successfully fetched document for resourceId: {} from index: {}", resourceId, pluginIndex); + + listener.onResponse(resourceSharing); + } + } catch (Exception e) { + LOGGER.error("Failed to parse document for resourceId: {} from index: {}", resourceId, pluginIndex, e); + listener.onFailure( + new ResourceSharingException( + "Failed to parse document for resourceId: " + resourceId + " from index: " + pluginIndex, + e + ) + ); + } + } + + @Override + public void onFailure(Exception e) { + + LOGGER.error("Failed to fetch document for resourceId: {} from index: {}", resourceId, pluginIndex, e); + listener.onFailure( + new ResourceSharingException( + "Failed to fetch document for resourceId: " + resourceId + " from index: " + pluginIndex, + e + ) + ); + + } + }); + } catch (Exception e) { + LOGGER.error("Failed to fetch document for resourceId: {} from index: {}", resourceId, pluginIndex, e); + listener.onFailure( + new ResourceSharingException("Failed to fetch document for resourceId: " + resourceId + " from index: " + pluginIndex, e) + ); + } + } + + /** + * Updates the sharing configuration for an existing resource in the resource sharing index. + * NOTE: This method only grants new access. To remove access use {@link #revokeAccess(String, String, Map, Set, String, boolean, ActionListener)} + * This method modifies the sharing permissions for a specific resource identified by its + * resource ID and source index. + * + * @param resourceId The unique identifier of the resource whose sharing configuration needs to be updated + * @param sourceIdx The source index where the original resource is stored + * @param requestUserName The user requesting to revoke the resource + * @param shareWith Updated sharing configuration object containing access control settings: + * { + * "scope": { + * "users": ["user1", "user2"], + * "roles": ["role1", "role2"], + * "backend_roles": ["backend_role1"] + * } + * } + * @param isAdmin Boolean indicating whether the user requesting to revoke is an admin or not + * @param listener Listener to be notified when the operation completes + * @throws RuntimeException if there's an error during the update operation + */ + public void updateResourceSharingInfo( + String resourceId, + String sourceIdx, + String requestUserName, + ShareWith shareWith, + boolean isAdmin, + ActionListener listener + ) { + XContentBuilder builder; + Map shareWithMap; + try { + builder = XContentFactory.jsonBuilder(); + shareWith.toXContent(builder, ToXContent.EMPTY_PARAMS); + String json = builder.toString(); + shareWithMap = DefaultObjectMapper.readValue(json, new TypeReference<>() { + }); + } catch (IOException e) { + LOGGER.error("Failed to build json content", e); + listener.onFailure(new ResourceSharingException("Failed to build json content", e)); + return; + } + + StepListener fetchDocListener = new StepListener<>(); + StepListener updateScriptListener = new StepListener<>(); + StepListener updatedSharingListener = new StepListener<>(); + + // Fetch resource sharing doc + fetchDocumentById(sourceIdx, resourceId, fetchDocListener); + + // build update script + fetchDocListener.whenComplete(currentSharingInfo -> { + // Check if user can share. At present only the resource creator and admin is allowed to share the resource + if (!isAdmin && currentSharingInfo != null && !currentSharingInfo.getCreatedBy().getCreator().equals(requestUserName)) { + + LOGGER.error("User {} is not authorized to share resource {}", requestUserName, resourceId); + listener.onFailure( + new ResourceSharingException("User " + requestUserName + " is not authorized to share resource " + resourceId) + ); + } + + Script updateScript = new Script(ScriptType.INLINE, "painless", """ + if (ctx._source.share_with == null) { + ctx._source.share_with = [:]; + } + + for (def entry : params.shareWith.entrySet()) { + def scopeName = entry.getKey(); + def newScope = entry.getValue(); + + if (!ctx._source.share_with.containsKey(scopeName)) { + def newScopeEntry = [:]; + for (def field : newScope.entrySet()) { + if (field.getValue() != null && !field.getValue().isEmpty()) { + newScopeEntry[field.getKey()] = new HashSet(field.getValue()); + } + } + ctx._source.share_with[scopeName] = newScopeEntry; + } else { + def existingScope = ctx._source.share_with[scopeName]; + + for (def field : newScope.entrySet()) { + def fieldName = field.getKey(); + def newValues = field.getValue(); + + if (newValues != null && !newValues.isEmpty()) { + if (!existingScope.containsKey(fieldName)) { + existingScope[fieldName] = new HashSet(); + } + + for (def value : newValues) { + if (!existingScope[fieldName].contains(value)) { + existingScope[fieldName].add(value); + } + } + } + } + } + } + """, Collections.singletonMap("shareWith", shareWithMap)); + + updateByQueryResourceSharing(sourceIdx, resourceId, updateScript, updateScriptListener); + + }, listener::onFailure); + + // Build & return the updated ResourceSharing + updateScriptListener.whenComplete(success -> { + if (!success) { + LOGGER.error("Failed to update resource sharing info for resource {}", resourceId); + listener.onResponse(null); + return; + } + // TODO check if this should be replaced by Java in-memory computation (current intuition is that it will be more memory + // intensive to do it in java) + fetchDocumentById(sourceIdx, resourceId, updatedSharingListener); + }, listener::onFailure); + + updatedSharingListener.whenComplete(listener::onResponse, listener::onFailure); + } + + /** + * Revokes access for specified entities from a resource sharing document. This method removes the specified + * entities (users, roles, or backend roles) from the existing sharing configuration while preserving other + * sharing settings. + * + *

The method performs the following steps: + *

    + *
  1. Fetches the existing document
  2. + *
  3. Removes specified entities from their respective lists in all sharing groups
  4. + *
  5. Updates the document if modifications were made
  6. + *
  7. Returns the updated resource sharing configuration
  8. + *
+ * + *

Example document structure: + *

+     * {
+     *   "source_idx": "resource_index_name",
+     *   "resource_id": "resource_id",
+     *   "share_with": {
+     *     "scope": {
+     *       "users": ["user1", "user2"],
+     *       "roles": ["role1", "role2"],
+     *       "backend_roles": ["backend_role1"]
+     *     }
+     *   }
+     * }
+     * 
+ * + * @param resourceId The ID of the resource from which to revoke access + * @param sourceIdx The name of the system index where the resource exists + * @param revokeAccess A map containing entity types (USER, ROLE, BACKEND_ROLE) and their corresponding + * values to be removed from the sharing configuration + * @param scopes A get of scopes to revoke access from. If null or empty, access is revoked from all scopes + * @param requestUserName The user trying to revoke the accesses + * @param isAdmin Boolean indicating whether the user is an admin or not + * @param listener Listener to be notified when the operation completes + * @throws IllegalArgumentException if resourceId, sourceIdx is null/empty, or if revokeAccess is null/empty + * @throws RuntimeException if the update operation fails or encounters an error + * @apiNote This method modifies the existing document. If no modifications are needed (i.e., specified + * entities don't exist in the current configuration), the original document is returned unchanged. + * @example + *
+     * Map> revokeAccess = new HashMap<>();
+     * revokeAccess.put(RecipientType.USER, Set.of("user1", "user2"));
+     * revokeAccess.put(RecipientType.ROLE, Set.of("role1"));
+     * ResourceSharing updated = revokeAccess("resourceId", "pluginIndex", revokeAccess);
+     * 
+ * @see RecipientType + * @see ResourceSharing + */ + public void revokeAccess( + String resourceId, + String sourceIdx, + Map> revokeAccess, + Set scopes, + String requestUserName, + boolean isAdmin, + ActionListener listener + ) { + if (StringUtils.isBlank(resourceId) || StringUtils.isBlank(sourceIdx) || revokeAccess == null || revokeAccess.isEmpty()) { + listener.onFailure(new IllegalArgumentException("resourceId, sourceIdx, and revokeAccess must not be null or empty")); + return; + } + + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + + LOGGER.debug( + "Revoking access for resource {} in {} for entities: {} and scopes: {}", + resourceId, + sourceIdx, + revokeAccess, + scopes + ); + + StepListener currentSharingListener = new StepListener<>(); + StepListener revokeUpdateListener = new StepListener<>(); + StepListener updatedSharingListener = new StepListener<>(); + + // Fetch the current ResourceSharing document + fetchDocumentById(sourceIdx, resourceId, currentSharingListener); + + // Check permissions & build revoke script + currentSharingListener.whenComplete(currentSharingInfo -> { + // Only admin or the creator of the resource is currently allowed to revoke access + if (!isAdmin && currentSharingInfo != null && !currentSharingInfo.getCreatedBy().getCreator().equals(requestUserName)) { + listener.onFailure( + new ResourceSharingException( + "User " + requestUserName + " is not authorized to revoke access to resource " + resourceId + ) + ); + } + + Map revoke = new HashMap<>(); + for (Map.Entry> entry : revokeAccess.entrySet()) { + revoke.put(entry.getKey().type().toLowerCase(), new ArrayList<>(entry.getValue())); + } + List scopesToUse = (scopes != null) ? new ArrayList<>(scopes) : new ArrayList<>(); + + Script revokeScript = new Script(ScriptType.INLINE, "painless", """ + if (ctx._source.share_with != null) { + Set scopesToProcess = new HashSet(params.scopes.isEmpty() ? ctx._source.share_with.keySet() : params.scopes); + + for (def scopeName : scopesToProcess) { + if (ctx._source.share_with.containsKey(scopeName)) { + def existingScope = ctx._source.share_with.get(scopeName); + + for (def entry : params.revokeAccess.entrySet()) { + def RecipientType = entry.getKey(); + def entitiesToRemove = entry.getValue(); + + if (existingScope.containsKey(RecipientType) && existingScope[RecipientType] != null) { + if (!(existingScope[RecipientType] instanceof HashSet)) { + existingScope[RecipientType] = new HashSet(existingScope[RecipientType]); + } + + existingScope[RecipientType].removeAll(entitiesToRemove); + + if (existingScope[RecipientType].isEmpty()) { + existingScope.remove(RecipientType); + } + } + } + + if (existingScope.isEmpty()) { + ctx._source.share_with.remove(scopeName); + } + } + } + } + """, Map.of("revokeAccess", revoke, "scopes", scopesToUse)); + updateByQueryResourceSharing(sourceIdx, resourceId, revokeScript, revokeUpdateListener); + + }, listener::onFailure); + + // Return doc or null based on successful result, fail otherwise + revokeUpdateListener.whenComplete(success -> { + if (!success) { + LOGGER.error("Failed to revoke access for resource {} in index {} (no docs updated).", resourceId, sourceIdx); + listener.onResponse(null); + return; + } + // TODO check if this should be replaced by Java in-memory computation (current intuition is that it will be more memory + // intensive to do it in java) + fetchDocumentById(sourceIdx, resourceId, updatedSharingListener); + }, listener::onFailure); + + updatedSharingListener.whenComplete(listener::onResponse, listener::onFailure); + } + } + + /** + * Deletes resource sharing records that match the specified source index and resource ID. + * This method performs a delete-by-query operation in the resource sharing index. + * + *

The method executes the following steps: + *

    + *
  1. Creates a delete-by-query request with a bool query
  2. + *
  3. Matches documents based on exact source index and resource ID
  4. + *
  5. Executes the delete operation with immediate refresh
  6. + *
  7. Returns the success/failure status based on deletion results
  8. + *
+ * + *

Example document structure that will be deleted: + *

+     * {
+     *   "source_idx": "source_index_name",
+     *   "resource_id": "resource_id_value",
+     *   "share_with": {
+     *     // sharing configuration
+     *   }
+     * }
+     * 
+ * + * @param sourceIdx The source index to match in the query (exact match) + * @param resourceId The resource ID to match in the query (exact match) + * @param listener The listener to be notified when the operation completes + * @throws IllegalArgumentException if sourceIdx or resourceId is null/empty + * @throws RuntimeException if the delete operation fails or encounters an error + * @implNote The delete operation uses a bool query with two must clauses to ensure exact matching: + *
+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx": sourceIdx } },
+     *         { "term": { "resource_id": resourceId } }
+     *       ]
+     *     }
+     *   }
+     * }
+     * 
+ */ + public void deleteResourceSharingRecord(String resourceId, String sourceIdx, ActionListener listener) { + LOGGER.debug( + "Deleting documents asynchronously from {} where source_idx = {} and resource_id = {}", + resourceSharingIndex, + sourceIdx, + resourceId + ); + + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + DeleteByQueryRequest dbq = new DeleteByQueryRequest(resourceSharingIndex).setQuery( + QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("source_idx.keyword", sourceIdx)) + .must(QueryBuilders.termQuery("resource_id.keyword", resourceId)) + ).setRefresh(true); + + client.execute(DeleteByQueryAction.INSTANCE, dbq, new ActionListener<>() { + @Override + public void onResponse(BulkByScrollResponse response) { + + long deleted = response.getDeleted(); + if (deleted > 0) { + LOGGER.debug("Successfully deleted {} documents from {}", deleted, resourceSharingIndex); + listener.onResponse(true); + } else { + LOGGER.debug( + "No documents found to delete in {} for source_idx: {} and resource_id: {}", + resourceSharingIndex, + sourceIdx, + resourceId + ); + // No documents were deleted + listener.onResponse(false); + } + } + + @Override + public void onFailure(Exception e) { + LOGGER.error("Failed to delete documents from {}", resourceSharingIndex, e); + listener.onFailure(e); + + } + }); + } catch (Exception e) { + LOGGER.error("Failed to delete documents from {} before request submission", resourceSharingIndex, e); + listener.onFailure(e); + } + } + + /** + * Deletes all resource sharing records that were created by a specific user. + * This method performs a delete-by-query operation to remove all documents where + * the created_by.user field matches the specified username. + * + *

The method executes the following steps: + *

    + *
  1. Validates the input username parameter
  2. + *
  3. Creates a delete-by-query request with term query matching
  4. + *
  5. Executes the delete operation with immediate refresh
  6. + *
  7. Returns the operation status based on number of deleted documents
  8. + *
+ * + *

Example query structure: + *

+     * {
+     *   "query": {
+     *     "term": {
+     *       "created_by.user": "username"
+     *     }
+     *   }
+     * }
+     * 
+ * + * @param name The username to match against the created_by.user field + * @param listener The listener to be notified when the operation completes + * @throws IllegalArgumentException if name is null or empty + * @implNote Implementation details: + *
    + *
  • Uses DeleteByQueryRequest for efficient bulk deletion
  • + *
  • Sets refresh=true for immediate consistency
  • + *
  • Uses term query for exact username matching
  • + *
  • Implements comprehensive error handling and logging
  • + *
+ *

+ * Example usage: + *

+     * boolean success = deleteAllRecordsForUser("john.doe");
+     * if (success) {
+     *     // Records were successfully deleted
+     * } else {
+     *     // No matching records found or operation failed
+     * }
+     * 
+ */ + public void deleteAllRecordsForUser(String name, ActionListener listener) { + if (StringUtils.isBlank(name)) { + listener.onFailure(new IllegalArgumentException("Username must not be null or empty")); + return; + } + + LOGGER.debug("Deleting all records for user {} asynchronously", name); + + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(resourceSharingIndex).setQuery( + QueryBuilders.termQuery("created_by.user", name) + ).setRefresh(true); + + client.execute(DeleteByQueryAction.INSTANCE, deleteRequest, new ActionListener<>() { + @Override + public void onResponse(BulkByScrollResponse response) { + long deletedDocs = response.getDeleted(); + if (deletedDocs > 0) { + LOGGER.debug("Successfully deleted {} documents created by user {}", deletedDocs, name); + listener.onResponse(true); + } else { + LOGGER.warn("No documents found for user {}", name); + // No documents matched => success = false + listener.onResponse(false); + } + } + + @Override + public void onFailure(Exception e) { + LOGGER.error("Failed to delete documents for user {}", name, e); + listener.onFailure(e); + } + }); + } catch (Exception e) { + LOGGER.error("Failed to delete documents for user {} before request submission", name, e); + listener.onFailure(e); + } + } + + /** + * Fetches all documents from the specified resource index and deserializes them into the specified class. + * + * @param resourceIndex The resource index to fetch documents from. + * @param parser The class to deserialize the documents into a specified type defined by the parser. + * @param listener The listener to be notified with the set of deserialized documents. + * @param The type of the deserialized documents. + */ + public void getResourceDocumentsFromIds( + Set resourceIds, + String resourceIndex, + ResourceParser parser, + ActionListener> listener + ) { + if (resourceIds.isEmpty()) { + listener.onResponse(new HashSet<>()); + return; + } + + // stashing Context to avoid permission issues in-case resourceIndex is a system index + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + MultiGetRequest request = new MultiGetRequest(); + for (String id : resourceIds) { + request.add(new MultiGetRequest.Item(resourceIndex, id)); + } + + client.multiGet(request, ActionListener.wrap(response -> { + Set result = new HashSet<>(); + try { + for (MultiGetItemResponse itemResponse : response.getResponses()) { + if (!itemResponse.isFailed() && itemResponse.getResponse().isExists()) { + BytesReference sourceAsString = itemResponse.getResponse().getSourceAsBytesRef(); + XContentParser xContentParser = XContentHelper.createParser( + NamedXContentRegistry.EMPTY, + LoggingDeprecationHandler.INSTANCE, + sourceAsString, + XContentType.JSON + ); + T resource = parser.parseXContent(xContentParser); + result.add(resource); + } + } + listener.onResponse(result); + } catch (Exception e) { + listener.onFailure(new ResourceSharingException("Failed to parse resources: " + e.getMessage(), e)); + } + }, e -> { + if (e instanceof IndexNotFoundException) { + LOGGER.error("Index {} does not exist", resourceIndex, e); + listener.onFailure(e); + } else { + LOGGER.error("Failed to fetch resources with ids {} from index {}", resourceIds, resourceIndex, e); + listener.onFailure(new ResourceSharingException("Failed to fetch resources: " + e.getMessage(), e)); + } + })); + } + } + + /** + * Updates resource sharing entries that match the specified source index and resource ID + * using the provided update script. This method performs an update-by-query operation + * in the resource sharing index. + * + *

The method executes the following steps: + *

    + *
  1. Creates a bool query to match exact source index and resource ID
  2. + *
  3. Constructs an update-by-query request with the query and update script
  4. + *
  5. Executes the update operation
  6. + *
  7. Returns success/failure status based on update results
  8. + *
+ * + *

Example document matching structure: + *

+     * {
+     *   "source_idx": "source_index_name",
+     *   "resource_id": "resource_id_value",
+     *   "share_with": {
+     *     // sharing configuration to be updated
+     *   }
+     * }
+     * 
+ * + * @param sourceIdx The source index to match in the query (exact match) + * @param resourceId The resource ID to match in the query (exact match) + * @param updateScript The script containing the update operations to be performed. + * This script defines how the matching documents should be modified + * @param listener Listener to be notified when the operation completes + * @apiNote This method: + *
    + *
  • Uses term queries for exact matching of source_idx and resource_id
  • + *
  • Returns false for both "no matching documents" and "operation failure" cases
  • + *
  • Logs the complete update request for debugging purposes
  • + *
  • Provides detailed logging for success and failure scenarios
  • + *
+ * @implNote The update operation uses a bool query with two must clauses: + *
+     * {
+     *   "query": {
+     *     "bool": {
+     *       "must": [
+     *         { "term": { "source_idx.keyword": sourceIdx } },
+     *         { "term": { "resource_id.keyword": resourceId } }
+     *       ]
+     *     }
+     *   }
+     * }
+     * 
+ */ + private void updateByQueryResourceSharing(String sourceIdx, String resourceId, Script updateScript, ActionListener listener) { + try (ThreadContext.StoredContext ctx = this.threadPool.getThreadContext().stashContext()) { + BoolQueryBuilder query = QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery("source_idx.keyword", sourceIdx)) + .must(QueryBuilders.termQuery("resource_id.keyword", resourceId)); + + UpdateByQueryRequest ubq = new UpdateByQueryRequest(resourceSharingIndex).setQuery(query) + .setScript(updateScript) + .setRefresh(true); + + client.execute(UpdateByQueryAction.INSTANCE, ubq, new ActionListener<>() { + @Override + public void onResponse(BulkByScrollResponse response) { + long updated = response.getUpdated(); + if (updated > 0) { + LOGGER.debug("Successfully updated {} documents in {}.", updated, resourceSharingIndex); + listener.onResponse(true); + } else { + LOGGER.debug( + "No documents found to update in {} for source_idx: {} and resource_id: {}", + resourceSharingIndex, + sourceIdx, + resourceId + ); + listener.onResponse(false); + } + } + + @Override + public void onFailure(Exception e) { + LOGGER.error("Failed to update documents in {}.", resourceSharingIndex, e); + listener.onFailure(e); + + } + }); + } catch (Exception e) { + LOGGER.error("Failed to update documents in {} before request submission.", resourceSharingIndex, e); + listener.onFailure(e); + } + } + + /** + * Helper method to execute a search request and collect resource IDs from the results. + * + * @param resourceIds List to collect resource IDs + * @param scroll Search Scroll + * @param searchRequest Request to execute + * @param boolQuery Query to execute with the request + * @param listener Listener to be notified when the operation completes + */ + private void executeSearchRequest( + Set resourceIds, + Scroll scroll, + SearchRequest searchRequest, + BoolQueryBuilder boolQuery, + ActionListener listener + ) { + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(boolQuery) + .size(1000) + .fetchSource(new String[] { "resource_id" }, null); + + searchRequest.source(searchSourceBuilder); + + StepListener searchStep = new StepListener<>(); + + client.search(searchRequest, searchStep); + + searchStep.whenComplete(initialResponse -> { + String scrollId = initialResponse.getScrollId(); + processScrollResults(resourceIds, scroll, scrollId, initialResponse.getHits().getHits(), listener); + }, listener::onFailure); + } + + /** + * Helper method to process scroll results recursively. + * + * @param resourceIds List to collect resource IDs + * @param scroll Search Scroll + * @param scrollId Scroll ID + * @param hits Search hits + * @param listener Listener to be notified when the operation completes + */ + private void processScrollResults( + Set resourceIds, + Scroll scroll, + String scrollId, + SearchHit[] hits, + ActionListener listener + ) { + // If no hits, clean up and complete + if (hits == null || hits.length == 0) { + clearScroll(scrollId, listener); + return; + } + + // Process current batch of hits + for (SearchHit hit : hits) { + Map sourceAsMap = hit.getSourceAsMap(); + if (sourceAsMap != null && sourceAsMap.containsKey("resource_id")) { + resourceIds.add(sourceAsMap.get("resource_id").toString()); + } + } + + // Prepare next scroll request + SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); + scrollRequest.scroll(scroll); + + // Execute next scroll + client.searchScroll(scrollRequest, ActionListener.wrap(scrollResponse -> { + // Process next batch recursively + processScrollResults(resourceIds, scroll, scrollResponse.getScrollId(), scrollResponse.getHits().getHits(), listener); + }, e -> { + // Clean up scroll context on failure + clearScroll(scrollId, ActionListener.wrap(r -> listener.onFailure(e), ex -> { + e.addSuppressed(ex); + listener.onFailure(e); + })); + })); + } + + /** + * Helper method to clear scroll context. + * + * @param scrollId Scroll ID + * @param listener Listener to be notified when the operation completes + */ + private void clearScroll(String scrollId, ActionListener listener) { + if (scrollId == null) { + listener.onResponse(null); + return; + } + + ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); + clearScrollRequest.addScrollId(scrollId); + + client.clearScroll(clearScrollRequest, ActionListener.wrap(r -> listener.onResponse(null), e -> { + LOGGER.warn("Failed to clear scroll context", e); + listener.onResponse(null); + })); + } + +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexManagementRepository.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexManagementRepository.java new file mode 100644 index 0000000000..166d410f86 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexManagementRepository.java @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.resources; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * This class is responsible for managing the resource sharing index. + * It provides methods to create the index if it doesn't exist. + * + * @opensearch.experimental + */ +public class ResourceSharingIndexManagementRepository { + + private static final Logger LOGGER = LogManager.getLogger(ResourceSharingIndexManagementRepository.class); + + private final ResourceSharingIndexHandler resourceSharingIndexHandler; + private final boolean resourceSharingEnabled; + + protected ResourceSharingIndexManagementRepository( + final ResourceSharingIndexHandler resourceSharingIndexHandler, + boolean isResourceSharingEnabled + ) { + this.resourceSharingIndexHandler = resourceSharingIndexHandler; + this.resourceSharingEnabled = isResourceSharingEnabled; + } + + public static ResourceSharingIndexManagementRepository create( + ResourceSharingIndexHandler resourceSharingIndexHandler, + boolean isResourceSharingEnabled + ) { + return new ResourceSharingIndexManagementRepository(resourceSharingIndexHandler, isResourceSharingEnabled); + } + + /** + * Creates the resource sharing index if it doesn't already exist. + * This method is called during the initialization phase of the repository. + * It ensures that the index is set up with the necessary mappings and settings + * before any operations are performed on the index. + */ + public void createResourceSharingIndexIfAbsent() { + // TODO check if this should be wrapped in an atomic completable future + if (resourceSharingEnabled) { + LOGGER.debug("Attempting to create Resource Sharing index"); + this.resourceSharingIndexHandler.createResourceSharingIndexIfAbsent(() -> null); + } + + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessAction.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessAction.java new file mode 100644 index 0000000000..5820d21a8c --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessAction.java @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import org.opensearch.action.ActionType; + +/** + * This class represents the action type for resource access. + * It is used to execute the resource access request and retrieve the response. + * + * @opensearch.experimental + */ +public class ResourceAccessAction extends ActionType { + + public static final ResourceAccessAction INSTANCE = new ResourceAccessAction(); + + public static final String NAME = "cluster:admin/security/resource_access"; + + private ResourceAccessAction() { + super(NAME, ResourceAccessResponse::new); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequest.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequest.java new file mode 100644 index 0000000000..1df9c244bb --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequest.java @@ -0,0 +1,236 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.security.spi.resources.sharing.ShareWith; + +/** + * This class represents a request to access a resource. + * It encapsulates the operation, resource ID, resource index, scope, share with information, revoked entities, and scopes. + * + * @opensearch.experimental + */ +public class ResourceAccessRequest extends ActionRequest { + + public enum Operation { + LIST, + SHARE, + REVOKE, + VERIFY + } + + private final Operation operation; + private final String resourceId; + private final String resourceIndex; + private final ShareWith shareWith; + private final Map> revokedEntities; + private final Set scopes; + + /** + * Private constructor to enforce usage of Builder + */ + private ResourceAccessRequest(Builder builder) { + this.operation = builder.operation; + this.resourceId = builder.resourceId; + this.resourceIndex = builder.resourceIndex; + this.shareWith = builder.shareWith; + this.revokedEntities = builder.revokedEntities; + this.scopes = builder.scopes; + } + + /** + * Static factory method to initialize ResourceAccessRequest from a Map. + */ + @SuppressWarnings("unchecked") + public static ResourceAccessRequest from(Map source, Map params) throws IOException { + Builder builder = new Builder(); + + if (source.containsKey("operation")) { + builder.operation((Operation) source.get("operation")); + } else { + throw new IllegalArgumentException("Missing required field: operation"); + } + + builder.resourceId((String) source.get("resource_id")); + String resourceIndex = params.getOrDefault("resource_index", (String) source.get("resource_index")); + if (StringUtils.isEmpty(resourceIndex)) { + throw new IllegalArgumentException("Missing required field: resource_index"); + } + builder.resourceIndex(resourceIndex); + + if (source.containsKey("share_with")) { + builder.shareWith((Map) source.get("share_with")); + } + + if (source.containsKey("entities_to_revoke")) { + builder.revokedEntities((Map) source.get("entities_to_revoke")); + } + + if (source.containsKey("scopes")) { + builder.scopes(Set.copyOf((List) source.get("scopes"))); // Ensuring Set type + } + + return builder.build(); + } + + public ResourceAccessRequest(StreamInput in) throws IOException { + super(in); + this.operation = in.readEnum(Operation.class); + this.resourceId = in.readOptionalString(); + this.resourceIndex = in.readOptionalString(); + this.shareWith = in.readOptionalWriteable(ShareWith::new); + this.revokedEntities = in.readMap(StreamInput::readString, valIn -> valIn.readSet(StreamInput::readString)); + this.scopes = in.readSet(StreamInput::readString); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeEnum(operation); + out.writeOptionalString(resourceId); + out.writeOptionalString(resourceIndex); + out.writeOptionalWriteable(shareWith); + out.writeMap(revokedEntities, StreamOutput::writeString, StreamOutput::writeStringCollection); + out.writeStringCollection(scopes); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public Operation getOperation() { + return operation; + } + + public String getResourceId() { + return resourceId; + } + + public String getResourceIndex() { + return resourceIndex; + } + + public ShareWith getShareWith() { + return shareWith; + } + + public Map> getRevokedEntities() { + return revokedEntities; + } + + public Set getScopes() { + return scopes; + } + + /** + * Builder for ResourceAccessRequest + */ + public static class Builder { + private Operation operation; + private String resourceId; + private String resourceIndex; + private ShareWith shareWith; + private Map> revokedEntities; + private Set scopes; + + public Builder operation(Operation operation) { + this.operation = operation; + return this; + } + + public Builder resourceId(String resourceId) { + this.resourceId = resourceId; + return this; + } + + public Builder resourceIndex(String resourceIndex) { + this.resourceIndex = resourceIndex; + return this; + } + + public Builder shareWith(Map source) { + try { + this.shareWith = parseShareWith(source); + } catch (Exception e) { + this.shareWith = null; + } + return this; + } + + public Builder revokedEntities(Map source) { + try { + this.revokedEntities = parseRevokedEntities(source); + } catch (Exception e) { + this.revokedEntities = null; + } + return this; + } + + public Builder scopes(Set scopes) { + this.scopes = scopes; + return this; + } + + public ResourceAccessRequest build() { + return new ResourceAccessRequest(this); + } + + private ShareWith parseShareWith(Map source) throws IOException { + if (source == null || source.isEmpty()) { + throw new IllegalArgumentException("share_with is required and cannot be empty"); + } + + String jsonString = XContentFactory.jsonBuilder().map(source).toString(); + + try ( + XContentParser parser = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, jsonString) + ) { + + return ShareWith.fromXContent(parser); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid share_with structure: " + e.getMessage(), e); + } + } + + private Map> parseRevokedEntities(Map source) { + + return source.entrySet() + .stream() + .filter(entry -> entry.getValue() instanceof Collection) + .collect( + Collectors.toMap( + Map.Entry::getKey, + entry -> ((Collection) entry.getValue()).stream() + .filter(String.class::isInstance) + .map(String.class::cast) + .collect(Collectors.toSet()) + ) + ); + } + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequestParams.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequestParams.java new file mode 100644 index 0000000000..880cfe00ec --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRequestParams.java @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import java.io.IOException; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.common.io.stream.StreamOutput; + +/** + * This class is used to represent the request parameters for resource access. + * It implements the NamedWriteable interface to allow serialization and deserialization of the request parameters. + * + * @opensearch.experimental + */ +public class ResourceAccessRequestParams implements NamedWriteable { + @Override + public String getWriteableName() { + return "resource_access_request_params"; + } + + @Override + public void writeTo(StreamOutput streamOutput) throws IOException { + + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessResponse.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessResponse.java new file mode 100644 index 0000000000..ac3ebf602f --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessResponse.java @@ -0,0 +1,98 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.sharing.ResourceSharing; + +/** + * This class is used to represent the response of a resource access request. + * It contains the response type and the response data. + * + * @opensearch.experimental + */ +public class ResourceAccessResponse extends ActionResponse implements ToXContentObject { + public enum ResponseType { + RESOURCES, + RESOURCE_SHARING, + BOOLEAN + } + + private final ResponseType responseType; + private final Object responseData; + + public ResourceAccessResponse(final StreamInput in) throws IOException { + this.responseType = in.readEnum(ResponseType.class); + this.responseData = null; + } + + public ResourceAccessResponse(Set resources) { + this.responseType = ResponseType.RESOURCES; + this.responseData = resources; + } + + public ResourceAccessResponse(ResourceSharing resourceSharing) { + this.responseType = ResponseType.RESOURCE_SHARING; + this.responseData = resourceSharing; + } + + public ResourceAccessResponse(boolean hasPermission) { + this.responseType = ResponseType.BOOLEAN; + this.responseData = hasPermission; + } + + @SuppressWarnings("unchecked") + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeEnum(responseType); + switch (responseType) { + case RESOURCES -> out.writeCollection((Set) responseData); + case RESOURCE_SHARING -> ((ResourceSharing) responseData).writeTo(out); + case BOOLEAN -> out.writeBoolean((Boolean) responseData); + } + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + switch (responseType) { + case RESOURCES -> builder.field("resources", responseData); + case RESOURCE_SHARING -> builder.field("sharing_info", responseData); + case BOOLEAN -> builder.field("has_permission", responseData); + } + return builder.endObject(); + } + + @SuppressWarnings("unchecked") + public Set getResources() { + return responseType == ResponseType.RESOURCES ? (Set) responseData : Collections.emptySet(); + } + + public ResourceSharing getResourceSharing() { + return responseType == ResponseType.RESOURCE_SHARING ? (ResourceSharing) responseData : null; + } + + public Boolean getHasPermission() { + return responseType == ResponseType.BOOLEAN ? (Boolean) responseData : null; + } + + @Override + public String toString() { + return "ResourceAccessResponse [responseType=" + responseType + ", responseData=" + responseData + "]"; + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java new file mode 100644 index 0000000000..700a064ed5 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java @@ -0,0 +1,151 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.ImmutableList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.transport.client.node.NodeClient; + +import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequest; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbidden; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.unauthorized; +import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.LIST; +import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.REVOKE; +import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.SHARE; +import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.VERIFY; +import static org.opensearch.security.common.support.Utils.PLUGIN_RESOURCE_ROUTE_PREFIX; +import static org.opensearch.security.common.support.Utils.addRoutesPrefix; + +/** + * This class handles the REST API for resource access management. + * It provides endpoints for listing, revoking, sharing, and verifying resource access. + * + * @opensearch.experimental + */ +public class ResourceAccessRestAction extends BaseRestHandler { + private static final Logger LOGGER = LogManager.getLogger(ResourceAccessRestAction.class); + + public ResourceAccessRestAction() {} + + @Override + public List routes() { + return addRoutesPrefix( + ImmutableList.of( + new Route(GET, "/list/{resource_index}"), + new Route(POST, "/revoke"), + new Route(POST, "/share"), + new Route(POST, "/verify_access") + ), + PLUGIN_RESOURCE_ROUTE_PREFIX + ); + } + + @Override + public String getName() { + return "resource_api_action"; + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + consumeParams(request); // early consume params to avoid 400s + + Map source = new HashMap<>(); + if (request.hasContent()) { + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + } + + String path = request.path().split(PLUGIN_RESOURCE_ROUTE_PREFIX)[1].split("/")[1]; + switch (path) { + case "list" -> source.put("operation", LIST); + case "revoke" -> source.put("operation", REVOKE); + case "share" -> source.put("operation", SHARE); + case "verify_access" -> source.put("operation", VERIFY); + default -> { + return channel -> badRequest(channel, "Unknown route: " + path); + } + } + + ResourceAccessRequest resourceAccessRequest = ResourceAccessRequest.from(source, request.params()); + return channel -> { + client.executeLocally(ResourceAccessAction.INSTANCE, resourceAccessRequest, new ActionListener<>() { + + @Override + public void onResponse(ResourceAccessResponse response) { + try { + sendResponse(channel, response); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void onFailure(Exception e) { + handleError(channel, e); + } + + }); + }; + } + + /** + * Consume params early to avoid 400s. + * + * @param request from which the params must be consumed + */ + private void consumeParams(RestRequest request) { + request.param("resource_index", ""); + } + + /** + * Send the appropriate response to the channel. + * @param channel the channel to send the response to + * @param response the response to send + * @throws IOException if an I/O error occurs + */ + private void sendResponse(RestChannel channel, ResourceAccessResponse response) throws IOException { + ok(channel, response::toXContent); + } + + /** + * Handle errors that occur during request processing. + * @param channel the channel to send the error response to + * @param e the exception that caused the error + */ + private void handleError(RestChannel channel, Exception e) { + String message = e.getMessage(); + LOGGER.error(message, e); + if (message.contains("not authorized")) { + forbidden(channel, message); + } else if (message.contains("no authenticated")) { + unauthorized(channel); + } else if (message.contains("not a system index")) { + badRequest(channel, message); + } + channel.sendResponse(new BytesRestResponse(RestStatus.INTERNAL_SERVER_ERROR, message)); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessTransportAction.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessTransportAction.java new file mode 100644 index 0000000000..6bd58246c8 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessTransportAction.java @@ -0,0 +1,117 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.security.common.resources.rest; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.indices.SystemIndices; +import org.opensearch.security.common.resources.ResourceAccessHandler; +import org.opensearch.security.spi.resources.exceptions.ResourceSharingException; +import org.opensearch.security.spi.resources.sharing.RecipientType; +import org.opensearch.security.spi.resources.sharing.RecipientTypeRegistry; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +/** + * Transport action for handling resource access requests. + * + * @opensearch.experimental + */ +public class ResourceAccessTransportAction extends HandledTransportAction { + private final ResourceAccessHandler resourceAccessHandler; + + private final SystemIndices systemIndices; + + @Inject + public ResourceAccessTransportAction( + TransportService transportService, + ActionFilters actionFilters, + SystemIndices systemIndices, + ResourceAccessHandler resourceAccessHandler + ) { + super(ResourceAccessAction.NAME, transportService, actionFilters, ResourceAccessRequest::new); + this.systemIndices = systemIndices; + this.resourceAccessHandler = resourceAccessHandler; + } + + @Override + protected void doExecute(Task task, ResourceAccessRequest request, ActionListener actionListener) { + // verify that the request if for a system index + if (!this.systemIndices.isSystemIndex(request.getResourceIndex())) { + actionListener.onFailure( + new ResourceSharingException("Resource index '" + request.getResourceIndex() + "' is not a system index.") + ); + return; + } + + switch (request.getOperation()) { + case LIST: + handleListResources(request, actionListener); + break; + case SHARE: + handleGrantAccess(request, actionListener); + break; + case REVOKE: + handleRevokeAccess(request, actionListener); + break; + case VERIFY: + handleVerifyAccess(request, actionListener); + break; + default: + actionListener.onFailure(new IllegalArgumentException("Unknown action type: " + request.getOperation())); + } + } + + private void handleListResources(ResourceAccessRequest request, ActionListener listener) { + resourceAccessHandler.getAccessibleResourcesForCurrentUser( + request.getResourceIndex(), + ActionListener.wrap(resources -> listener.onResponse(new ResourceAccessResponse(resources)), listener::onFailure) + ); + } + + private void handleGrantAccess(ResourceAccessRequest request, ActionListener listener) { + resourceAccessHandler.shareWith( + request.getResourceId(), + request.getResourceIndex(), + request.getShareWith(), + ActionListener.wrap(response -> listener.onResponse(new ResourceAccessResponse(response)), listener::onFailure) + ); + } + + private void handleRevokeAccess(ResourceAccessRequest request, ActionListener listener) { + resourceAccessHandler.revokeAccess( + request.getResourceId(), + request.getResourceIndex(), + parseRevokedEntities(request.getRevokedEntities()), + request.getScopes(), + ActionListener.wrap(success -> listener.onResponse(new ResourceAccessResponse(success)), listener::onFailure) + ); + } + + private void handleVerifyAccess(ResourceAccessRequest request, ActionListener listener) { + resourceAccessHandler.hasPermission( + request.getResourceId(), + request.getResourceIndex(), + request.getScopes(), + ActionListener.wrap(hasPermission -> listener.onResponse(new ResourceAccessResponse(hasPermission)), listener::onFailure) + ); + } + + private Map> parseRevokedEntities(Map> revokeSource) { + return revokeSource.entrySet() + .stream() + .collect(Collectors.toMap(entry -> RecipientTypeRegistry.fromValue(entry.getKey()), Map.Entry::getValue)); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/support/ConfigConstants.java b/common/src/main/java/org/opensearch/security/common/support/ConfigConstants.java new file mode 100644 index 0000000000..2aafb9898a --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/support/ConfigConstants.java @@ -0,0 +1,404 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.support; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.auditlog.impl.AuditCategory; + +import com.password4j.types.Hmac; + +public class ConfigConstants { + + public static final String OPENDISTRO_SECURITY_CONFIG_PREFIX = "_opendistro_security_"; + public static final String SECURITY_SETTINGS_PREFIX = "plugins.security."; + + public static final String OPENSEARCH_SECURITY_DISABLED = SECURITY_SETTINGS_PREFIX + "disabled"; + public static final boolean OPENSEARCH_SECURITY_DISABLED_DEFAULT = false; + + public static final String OPENDISTRO_SECURITY_CHANNEL_TYPE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "channel_type"; + + public static final String OPENDISTRO_SECURITY_ORIGIN = OPENDISTRO_SECURITY_CONFIG_PREFIX + "origin"; + public static final String OPENDISTRO_SECURITY_ORIGIN_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "origin_header"; + + public static final String OPENDISTRO_SECURITY_DLS_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_query"; + + public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "dls_filter_level_query"; + public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "dls_filter_level_query_t"; + + public static final String OPENDISTRO_SECURITY_DLS_MODE_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_mode"; + public static final String OPENDISTRO_SECURITY_DLS_MODE_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_mode_t"; + + public static final String OPENDISTRO_SECURITY_FLS_FIELDS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "fls_fields"; + + public static final String OPENDISTRO_SECURITY_MASKED_FIELD_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "masked_fields"; + + public static final String OPENDISTRO_SECURITY_DOC_ALLOWLIST_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "doc_allowlist"; + public static final String OPENDISTRO_SECURITY_DOC_ALLOWLIST_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "doc_allowlist_t"; + + public static final String OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "filter_level_dls_done"; + + public static final String OPENDISTRO_SECURITY_DLS_QUERY_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_query_ccs"; + + public static final String OPENDISTRO_SECURITY_FLS_FIELDS_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "fls_fields_ccs"; + + public static final String OPENDISTRO_SECURITY_MASKED_FIELD_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "masked_fields_ccs"; + + public static final String OPENDISTRO_SECURITY_CONF_REQUEST_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "conf_request"; + + public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "remote_address"; + public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "remote_address_header"; + + public static final String OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "initial_action_class_header"; + + /** + * Set by SSL plugin for https requests only + */ + public static final String OPENDISTRO_SECURITY_SSL_PEER_CERTIFICATES = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_peer_certificates"; + + /** + * Set by SSL plugin for https requests only + */ + public static final String OPENDISTRO_SECURITY_SSL_PRINCIPAL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_principal"; + + /** + * If this is set to TRUE then the request comes from a Server Node (fully trust) + * Its expected that there is a _opendistro_security_user attached as header + */ + public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_INTERCLUSTER_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "ssl_transport_intercluster_request"; + + public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "ssl_transport_trustedcluster_request"; + + // CS-SUPPRESS-SINGLE: RegexpSingleline Extensions manager used to allow/disallow TLS connections to extensions + public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENSION_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX + + "ssl_transport_extension_request"; + // CS-ENFORCE-SINGLE + + /** + * Set by the SSL plugin, this is the peer node certificate on the transport layer + */ + public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_transport_principal"; + + public static final String OPENDISTRO_SECURITY_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user"; + public static final String OPENDISTRO_SECURITY_USER_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user_header"; + + // persistent header. This header is set once and cannot be stashed + public static final String OPENDISTRO_SECURITY_AUTHENTICATED_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "authenticated_user"; + + public static final String OPENDISTRO_SECURITY_INITIATING_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "_initiating_user"; + + public static final String OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user_info"; + + public static final String OPENDISTRO_SECURITY_INJECTED_USER = "injected_user"; + public static final String OPENDISTRO_SECURITY_INJECTED_USER_HEADER = "injected_user_header"; + + public static final String OPENDISTRO_SECURITY_XFF_DONE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "xff_done"; + + public static final String SSO_LOGOUT_URL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "sso_logout_url"; + + public static final String OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX = ".opendistro_security"; + + public static final String SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = SECURITY_SETTINGS_PREFIX + "enable_snapshot_restore_privilege"; + public static final boolean SECURITY_DEFAULT_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = true; + + public static final String SECURITY_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = SECURITY_SETTINGS_PREFIX + + "check_snapshot_restore_write_privileges"; + public static final boolean SECURITY_DEFAULT_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = true; + public static final Set SECURITY_SNAPSHOT_RESTORE_NEEDED_WRITE_PRIVILEGES = Collections.unmodifiableSet( + new HashSet(Arrays.asList("indices:admin/create", "indices:data/write/index" + // "indices:data/write/bulk" + )) + ); + + public static final String SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX + + "cert.intercluster_request_evaluator_class"; + public static final String OPENDISTRO_SECURITY_ACTION_NAME = OPENDISTRO_SECURITY_CONFIG_PREFIX + "action_name"; + + public static final String SECURITY_AUTHCZ_ADMIN_DN = SECURITY_SETTINGS_PREFIX + "authcz.admin_dn"; + public static final String SECURITY_CONFIG_INDEX_NAME = SECURITY_SETTINGS_PREFIX + "config_index_name"; + public static final String SECURITY_AUTHCZ_IMPERSONATION_DN = SECURITY_SETTINGS_PREFIX + "authcz.impersonation_dn"; + public static final String SECURITY_AUTHCZ_REST_IMPERSONATION_USERS = SECURITY_SETTINGS_PREFIX + "authcz.rest_impersonation_user"; + + public static final String BCRYPT = "bcrypt"; + public static final String PBKDF2 = "pbkdf2"; + + public static final String SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.rounds"; + public static final int SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS_DEFAULT = 12; + public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.minor"; + public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR_DEFAULT = "Y"; + + public static final String SECURITY_PASSWORD_HASHING_ALGORITHM = SECURITY_SETTINGS_PREFIX + "password.hashing.algorithm"; + public static final String SECURITY_PASSWORD_HASHING_ALGORITHM_DEFAULT = BCRYPT; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS = SECURITY_SETTINGS_PREFIX + + "password.hashing.pbkdf2.iterations"; + public static final int SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS_DEFAULT = 600_000; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.length"; + public static final int SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH_DEFAULT = 256; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.function"; + public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION_DEFAULT = Hmac.SHA256.name(); + + public static final String SECURITY_AUDIT_TYPE_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.type"; + public static final String SECURITY_AUDIT_CONFIG_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.config"; + public static final String SECURITY_AUDIT_CONFIG_ROUTES = SECURITY_SETTINGS_PREFIX + "audit.routes"; + public static final String SECURITY_AUDIT_CONFIG_ENDPOINTS = SECURITY_SETTINGS_PREFIX + "audit.endpoints"; + public static final String SECURITY_AUDIT_THREADPOOL_SIZE = SECURITY_SETTINGS_PREFIX + "audit.threadpool.size"; + public static final String SECURITY_AUDIT_THREADPOOL_MAX_QUEUE_LEN = SECURITY_SETTINGS_PREFIX + "audit.threadpool.max_queue_len"; + public static final String OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY = "opendistro_security.audit.log_request_body"; + public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES = "opendistro_security.audit.resolve_indices"; + public static final String OPENDISTRO_SECURITY_AUDIT_ENABLE_REST = "opendistro_security.audit.enable_rest"; + public static final String OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT = "opendistro_security.audit.enable_transport"; + public static final String OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES = + "opendistro_security.audit.config.disabled_transport_categories"; + public static final String OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES = + "opendistro_security.audit.config.disabled_rest_categories"; + public static final List OPENDISTRO_SECURITY_AUDIT_DISABLED_CATEGORIES_DEFAULT = ImmutableList.of( + AuditCategory.AUTHENTICATED.toString(), + AuditCategory.GRANTED_PRIVILEGES.toString() + ); + public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS = "opendistro_security.audit.ignore_users"; + public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS = "opendistro_security.audit.ignore_requests"; + public static final String SECURITY_AUDIT_IGNORE_HEADERS = SECURITY_SETTINGS_PREFIX + "audit.ignore_headers"; + public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS = "opendistro_security.audit.resolve_bulk_requests"; + public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_VERIFY_HOSTNAMES_DEFAULT = true; + public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_ENABLE_SSL_CLIENT_AUTH_DEFAULT = false; + public static final String OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS = "opendistro_security.audit.exclude_sensitive_headers"; + + public static final String SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX = SECURITY_SETTINGS_PREFIX + "audit.config."; + + // Internal Opensearch data_stream + public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_NAME = "data_stream.name"; + public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_MANAGE = "data_stream.template.manage"; + public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NAME = "data_stream.template.name"; + public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_REPLICAS = "data_stream.template.number_of_replicas"; + public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_SHARDS = "data_stream.template.number_of_shards"; + + // Internal / External OpenSearch + public static final String SECURITY_AUDIT_OPENSEARCH_INDEX = "index"; + public static final String SECURITY_AUDIT_OPENSEARCH_TYPE = "type"; + + // External OpenSearch + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_HTTP_ENDPOINTS = "http_endpoints"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME = "username"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD = "password"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL = "enable_ssl"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_VERIFY_HOSTNAMES = "verify_hostnames"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH = "enable_ssl_client_auth"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH = "pemkey_filepath"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_CONTENT = "pemkey_content"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_PASSWORD = "pemkey_password"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH = "pemcert_filepath"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_CONTENT = "pemcert_content"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH = "pemtrustedcas_filepath"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_CONTENT = "pemtrustedcas_content"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_JKS_CERT_ALIAS = "cert_alias"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_CIPHERS = "enabled_ssl_ciphers"; + public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_PROTOCOLS = "enabled_ssl_protocols"; + + // Webhooks + public static final String SECURITY_AUDIT_WEBHOOK_URL = "webhook.url"; + public static final String SECURITY_AUDIT_WEBHOOK_FORMAT = "webhook.format"; + public static final String SECURITY_AUDIT_WEBHOOK_SSL_VERIFY = "webhook.ssl.verify"; + public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_FILEPATH = "webhook.ssl.pemtrustedcas_filepath"; + public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_CONTENT = "webhook.ssl.pemtrustedcas_content"; + + // Log4j + public static final String SECURITY_AUDIT_LOG4J_LOGGER_NAME = "log4j.logger_name"; + public static final String SECURITY_AUDIT_LOG4J_LEVEL = "log4j.level"; + + // retry + public static final String SECURITY_AUDIT_RETRY_COUNT = SECURITY_SETTINGS_PREFIX + "audit.config.retry_count"; + public static final String SECURITY_AUDIT_RETRY_DELAY_MS = SECURITY_SETTINGS_PREFIX + "audit.config.retry_delay_ms"; + + public static final String SECURITY_KERBEROS_KRB5_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.krb5_filepath"; + public static final String SECURITY_KERBEROS_ACCEPTOR_KEYTAB_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_keytab_filepath"; + public static final String SECURITY_KERBEROS_ACCEPTOR_PRINCIPAL = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_principal"; + public static final String SECURITY_CERT_OID = SECURITY_SETTINGS_PREFIX + "cert.oid"; + public static final String SECURITY_CERT_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX + + "cert.intercluster_request_evaluator_class"; + public static final String SECURITY_ADVANCED_MODULES_ENABLED = SECURITY_SETTINGS_PREFIX + "advanced_modules_enabled"; + public static final String SECURITY_NODES_DN = SECURITY_SETTINGS_PREFIX + "nodes_dn"; + public static final String SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED = SECURITY_SETTINGS_PREFIX + "nodes_dn_dynamic_config_enabled"; + public static final String SECURITY_DISABLED = SECURITY_SETTINGS_PREFIX + "disabled"; + + public static final String SECURITY_CACHE_TTL_MINUTES = SECURITY_SETTINGS_PREFIX + "cache.ttl_minutes"; + public static final String SECURITY_ALLOW_UNSAFE_DEMOCERTIFICATES = SECURITY_SETTINGS_PREFIX + "allow_unsafe_democertificates"; + public static final String SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX = SECURITY_SETTINGS_PREFIX + "allow_default_init_securityindex"; + + public static final String SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE = SECURITY_SETTINGS_PREFIX + + "allow_default_init_securityindex.use_cluster_state"; + + public static final String SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST = SECURITY_SETTINGS_PREFIX + + "background_init_if_securityindex_not_exist"; + + public static final String SECURITY_ROLES_MAPPING_RESOLUTION = SECURITY_SETTINGS_PREFIX + "roles_mapping_resolution"; + + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_METADATA_ONLY = + "opendistro_security.compliance.history.write.metadata_only"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_METADATA_ONLY = + "opendistro_security.compliance.history.read.metadata_only"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS = + "opendistro_security.compliance.history.read.watched_fields"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES = + "opendistro_security.compliance.history.write.watched_indices"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS = + "opendistro_security.compliance.history.write.log_diffs"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS = + "opendistro_security.compliance.history.read.ignore_users"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS = + "opendistro_security.compliance.history.write.ignore_users"; + public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED = + "opendistro_security.compliance.history.external_config_enabled"; + public static final String OPENDISTRO_SECURITY_SOURCE_FIELD_CONTEXT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "source_field_context"; + public static final String SECURITY_COMPLIANCE_DISABLE_ANONYMOUS_AUTHENTICATION = SECURITY_SETTINGS_PREFIX + + "compliance.disable_anonymous_authentication"; + public static final String SECURITY_COMPLIANCE_IMMUTABLE_INDICES = SECURITY_SETTINGS_PREFIX + "compliance.immutable_indices"; + public static final String SECURITY_COMPLIANCE_SALT = SECURITY_SETTINGS_PREFIX + "compliance.salt"; + public static final String SECURITY_COMPLIANCE_SALT_DEFAULT = "e1ukloTsQlOgPquJ";// 16 chars + public static final String SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED = + "opendistro_security.compliance.history.internal_config_enabled"; + public static final String SECURITY_SSL_ONLY = SECURITY_SETTINGS_PREFIX + "ssl_only"; + public static final String SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "plugins.security_config.ssl_dual_mode_enabled"; + public static final String SECURITY_SSL_DUAL_MODE_SKIP_SECURITY = OPENDISTRO_SECURITY_CONFIG_PREFIX + "passive_security"; + public static final String LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "opendistro_security_config.ssl_dual_mode_enabled"; + public static final String SECURITY_SSL_CERT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX + "ssl_cert_reload_enabled"; + public static final String SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX + + "ssl.certificates_hot_reload.enabled"; + public static final String SECURITY_DISABLE_ENVVAR_REPLACEMENT = SECURITY_SETTINGS_PREFIX + "disable_envvar_replacement"; + public static final String SECURITY_DFM_EMPTY_OVERRIDES_ALL = SECURITY_SETTINGS_PREFIX + "dfm_empty_overrides_all"; + + public enum RolesMappingResolution { + MAPPING_ONLY, + BACKENDROLES_ONLY, + BOTH + } + + public static final String SECURITY_FILTER_SECURITYINDEX_FROM_ALL_REQUESTS = SECURITY_SETTINGS_PREFIX + + "filter_securityindex_from_all_requests"; + public static final String SECURITY_DLS_MODE = SECURITY_SETTINGS_PREFIX + "dls.mode"; + // REST API + public static final String SECURITY_RESTAPI_ROLES_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.roles_enabled"; + public static final String SECURITY_RESTAPI_ADMIN_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.admin.enabled"; + public static final String SECURITY_RESTAPI_ENDPOINTS_DISABLED = SECURITY_SETTINGS_PREFIX + "restapi.endpoints_disabled"; + public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX = SECURITY_SETTINGS_PREFIX + "restapi.password_validation_regex"; + public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE = SECURITY_SETTINGS_PREFIX + + "restapi.password_validation_error_message"; + public static final String SECURITY_RESTAPI_PASSWORD_MIN_LENGTH = SECURITY_SETTINGS_PREFIX + "restapi.password_min_length"; + public static final String SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH = SECURITY_SETTINGS_PREFIX + + "restapi.password_score_based_validation_strength"; + // Illegal Opcodes from here on + public static final String SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.disable_rest_auth_initially"; + public static final String SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS = SECURITY_SETTINGS_PREFIX + + "unsupported.delay_initialization_seconds"; + public static final String SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.disable_intertransport_auth_initially"; + public static final String SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX + + "unsupported.passive_intertransport_auth_initially"; + public static final String SECURITY_UNSUPPORTED_RESTORE_SECURITYINDEX_ENABLED = SECURITY_SETTINGS_PREFIX + + "unsupported.restore.securityindex.enabled"; + public static final String SECURITY_UNSUPPORTED_INJECT_USER_ENABLED = SECURITY_SETTINGS_PREFIX + "unsupported.inject_user.enabled"; + public static final String SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED = SECURITY_SETTINGS_PREFIX + + "unsupported.inject_user.admin.enabled"; + public static final String SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS = SECURITY_SETTINGS_PREFIX + "unsupported.allow_now_in_dls"; + + public static final String SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION = SECURITY_SETTINGS_PREFIX + + "unsupported.restapi.allow_securityconfig_modification"; + public static final String SECURITY_UNSUPPORTED_LOAD_STATIC_RESOURCES = SECURITY_SETTINGS_PREFIX + "unsupported.load_static_resources"; + public static final String SECURITY_UNSUPPORTED_ACCEPT_INVALID_CONFIG = SECURITY_SETTINGS_PREFIX + "unsupported.accept_invalid_config"; + + public static final String SECURITY_PROTECTED_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.enabled"; + public static final Boolean SECURITY_PROTECTED_INDICES_ENABLED_DEFAULT = false; + public static final String SECURITY_PROTECTED_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.indices"; + public static final List SECURITY_PROTECTED_INDICES_DEFAULT = Collections.emptyList(); + public static final String SECURITY_PROTECTED_INDICES_ROLES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.roles"; + public static final List SECURITY_PROTECTED_INDICES_ROLES_DEFAULT = Collections.emptyList(); + + // Roles injection for plugins + public static final String OPENDISTRO_SECURITY_INJECTED_ROLES = "opendistro_security_injected_roles"; + public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_HEADER = "opendistro_security_injected_roles_header"; + + // Roles validation for the plugins + public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION = "opendistro_security_injected_roles_validation"; + public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION_HEADER = + "opendistro_security_injected_roles_validation_header"; + + // System indices settings + public static final String SYSTEM_INDEX_PERMISSION = "system:admin/system_index"; + public static final String SECURITY_SYSTEM_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.enabled"; + public static final Boolean SECURITY_SYSTEM_INDICES_ENABLED_DEFAULT = false; + public static final String SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + + "system_indices.permission.enabled"; + public static final Boolean SECURITY_SYSTEM_INDICES_PERMISSIONS_DEFAULT = false; + public static final String SECURITY_SYSTEM_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.indices"; + public static final List SECURITY_SYSTEM_INDICES_DEFAULT = Collections.emptyList(); + public static final String SECURITY_MASKED_FIELDS_ALGORITHM_DEFAULT = SECURITY_SETTINGS_PREFIX + "masked_fields.algorithm.default"; + + public static final String TENANCY_PRIVATE_TENANT_NAME = "private"; + public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; + public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; + + public static final String USE_JDK_SERIALIZATION = SECURITY_SETTINGS_PREFIX + "use_jdk_serialization"; + + // On-behalf-of endpoints settings + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings + public static final String EXTENSIONS_BWC_PLUGIN_MODE = "bwcPluginMode"; + public static final boolean EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT = false; + // CS-ENFORCE-SINGLE + + // Variable for initial admin password support + public static final String OPENSEARCH_INITIAL_ADMIN_PASSWORD = "OPENSEARCH_INITIAL_ADMIN_PASSWORD"; + + // Resource sharing feature-flag + public static final String OPENSEARCH_RESOURCE_SHARING_ENABLED = SECURITY_SETTINGS_PREFIX + "resource_sharing.enabled"; + public static final boolean OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT = true; + + public static Set getSettingAsSet( + final Settings settings, + final String key, + final List defaultList, + final boolean ignoreCaseForNone + ) { + final List list = settings.getAsList(key, defaultList); + if (list.size() == 1 && "NONE".equals(ignoreCaseForNone ? list.get(0).toUpperCase() : list.get(0))) { + return Collections.emptySet(); + } + return ImmutableSet.copyOf(list); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/support/Utils.java b/common/src/main/java/org/opensearch/security/common/support/Utils.java new file mode 100644 index 0000000000..ffdc8d9390 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/support/Utils.java @@ -0,0 +1,285 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.support; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.tuple.Pair; + +import org.opensearch.ExceptionsHelper; +import org.opensearch.OpenSearchParseException; +import org.opensearch.SpecialPermission; +import org.opensearch.common.CheckedSupplier; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.xcontent.XContentHelper; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.common.xcontent.json.JsonXContent; +import org.opensearch.core.common.Strings; +import org.opensearch.core.common.bytes.BytesReference; +import org.opensearch.core.common.transport.TransportAddress; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.NamedRoute; +import org.opensearch.rest.RestHandler.DeprecatedRoute; +import org.opensearch.rest.RestHandler.Route; +import org.opensearch.security.common.DefaultObjectMapper; +import org.opensearch.security.common.user.User; + +import static org.opensearch.core.xcontent.DeprecationHandler.THROW_UNSUPPORTED_OPERATION; + +public class Utils { + @Deprecated + public static final String LEGACY_OPENDISTRO_PREFIX = "_opendistro/_security"; + public static final String PLUGINS_PREFIX = "_plugins/_security"; + + public final static String PLUGIN_ROUTE_PREFIX = "/" + PLUGINS_PREFIX; + + @Deprecated + public final static String LEGACY_PLUGIN_ROUTE_PREFIX = "/" + LEGACY_OPENDISTRO_PREFIX; + + public final static String PLUGIN_API_ROUTE_PREFIX = PLUGIN_ROUTE_PREFIX + "/api"; + + @Deprecated + public final static String LEGACY_PLUGIN_API_ROUTE_PREFIX = LEGACY_PLUGIN_ROUTE_PREFIX + "/api"; + + public final static String OPENDISTRO_API_DEPRECATION_MESSAGE = + "[_opendistro/_security] is a deprecated endpoint path. Please use _plugins/_security instead."; + + public final static String PLUGIN_RESOURCE_ROUTE_PREFIX = PLUGIN_ROUTE_PREFIX + "/resources"; + + private static final ObjectMapper internalMapper = new ObjectMapper(); + + public static Map convertJsonToxToStructuredMap(ToXContent jsonContent) { + Map map = null; + try { + final BytesReference bytes = XContentHelper.toXContent(jsonContent, XContentType.JSON, false); + map = XContentHelper.convertToMap(bytes, false, XContentType.JSON).v2(); + } catch (IOException e1) { + throw ExceptionsHelper.convertToOpenSearchException(e1); + } + + return map; + } + + public static Map convertJsonToxToStructuredMap(String jsonContent) { + try ( + XContentParser parser = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, jsonContent) + ) { + return parser.map(); + } catch (IOException e1) { + throw ExceptionsHelper.convertToOpenSearchException(e1); + } + } + + private static BytesReference convertStructuredMapToBytes(Map structuredMap) { + try { + return BytesReference.bytes(JsonXContent.contentBuilder().map(structuredMap)); + } catch (IOException e) { + throw new OpenSearchParseException("Failed to convert map", e); + } + } + + public static String convertStructuredMapToJson(Map structuredMap) { + try { + return XContentHelper.convertToJson(convertStructuredMapToBytes(structuredMap), false, XContentType.JSON); + } catch (IOException e) { + throw new OpenSearchParseException("Failed to convert map", e); + } + } + + public static JsonNode convertJsonToJackson(BytesReference jsonContent) { + try { + return DefaultObjectMapper.readTree(jsonContent.utf8ToString()); + } catch (IOException e1) { + throw ExceptionsHelper.convertToOpenSearchException(e1); + } + + } + + public static JsonNode toJsonNode(final String content) throws IOException { + return DefaultObjectMapper.readTree(content); + } + + public static Object toConfigObject(final JsonNode content, final Class clazz) throws IOException { + return DefaultObjectMapper.readTree(content, clazz); + } + + public static JsonNode convertJsonToJackson(ToXContent jsonContent, boolean omitDefaults) { + try { + return DefaultObjectMapper.readTree( + Strings.toString( + XContentType.JSON, + jsonContent, + new ToXContent.MapParams(Map.of("omit_defaults", String.valueOf(omitDefaults))) + ) + ); + } catch (IOException e1) { + throw ExceptionsHelper.convertToOpenSearchException(e1); + } + + } + + @SuppressWarnings("removal") + public static byte[] jsonMapToByteArray(Map jsonAsMap) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) () -> internalMapper.writeValueAsBytes(jsonAsMap)); + } catch (final PrivilegedActionException e) { + if (e.getCause() instanceof JsonProcessingException) { + throw (JsonProcessingException) e.getCause(); + } else if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } else { + throw new RuntimeException(e.getCause()); + } + } + } + + @SuppressWarnings("removal") + public static Map byteArrayToMutableJsonMap(byte[] jsonBytes) throws IOException { + + final SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission(new SpecialPermission()); + } + + try { + return AccessController.doPrivileged( + (PrivilegedExceptionAction>) () -> internalMapper.readValue( + jsonBytes, + new TypeReference>() { + } + ) + ); + } catch (final PrivilegedActionException e) { + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } else if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } else { + throw new RuntimeException(e.getCause()); + } + } + } + + /** + * Generate field resource paths + * @param fields fields + * @param prefix prefix path + * @return new set of fields resource paths + */ + public static Set generateFieldResourcePaths(final Set fields, final String prefix) { + return fields.stream().map(field -> prefix + field).collect(ImmutableSet.toImmutableSet()); + } + + /** + * Add prefixes(_plugins/_security/api) to rest API routes + * @param routes routes + * @return new list of API routes prefixed with and _plugins/_security/api + */ + public static List addRoutesPrefix(List routes) { + return addRoutesPrefix(routes, PLUGIN_API_ROUTE_PREFIX); + } + + /** + * Add prefixes(_opendistro/_security/api) to rest API routes + * Deprecated in favor of addRoutesPrefix(List routes) + * @param routes routes + * @return new list of API routes prefixed with and _opendistro/_security/api + */ + @Deprecated + public static List addLegacyRoutesPrefix(List routes) { + return addDeprecatedRoutesPrefix(routes, LEGACY_PLUGIN_API_ROUTE_PREFIX); + } + + /** + * Add customized prefix(_opendistro... and _plugins...)to API rest routes + * @param routes routes + * @param prefixes all api prefix + * @return new list of API routes prefixed with the strings listed in prefixes + * Total number of routes will be expanded len(prefixes) as much comparing to the list passed in + */ + public static List addRoutesPrefix(List routes, final String... prefixes) { + return routes.stream().flatMap(r -> Arrays.stream(prefixes).map(p -> { + if (r instanceof NamedRoute) { + NamedRoute nr = (NamedRoute) r; + return new NamedRoute.Builder().method(nr.getMethod()) + .path(p + nr.getPath()) + .uniqueName(nr.name()) + .legacyActionNames(nr.actionNames()) + .build(); + } + return new Route(r.getMethod(), p + r.getPath()); + })).collect(ImmutableList.toImmutableList()); + } + + /** + * Add prefixes(_plugins...) to rest API routes + * @param deprecatedRoutes Routes being deprecated + * @return new list of API routes prefixed with _opendistro... and _plugins... + *Total number of routes is expanded as twice as the number of routes passed in + */ + public static List addDeprecatedRoutesPrefix(List deprecatedRoutes) { + return addDeprecatedRoutesPrefix(deprecatedRoutes, LEGACY_PLUGIN_API_ROUTE_PREFIX, PLUGIN_API_ROUTE_PREFIX); + } + + /** + * Add customized prefix(_opendistro... and _plugins...)to API rest routes + * @param deprecatedRoutes Routes being deprecated + * @param prefixes all api prefix + * @return new list of API routes prefixed with the strings listed in prefixes + * Total number of routes will be expanded len(prefixes) as much comparing to the list passed in + */ + public static List addDeprecatedRoutesPrefix(List deprecatedRoutes, final String... prefixes) { + return deprecatedRoutes.stream() + .flatMap(r -> Arrays.stream(prefixes).map(p -> new DeprecatedRoute(r.getMethod(), p + r.getPath(), r.getDeprecationMessage()))) + .collect(ImmutableList.toImmutableList()); + } + + public static Pair userAndRemoteAddressFrom(final ThreadContext threadContext) { + final User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); + final TransportAddress remoteAddress = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); + return Pair.of(user, remoteAddress); + } + + public static T withIOException(final CheckedSupplier action) { + try { + return action.get(); + } catch (final IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + +} diff --git a/common/src/main/java/org/opensearch/security/common/support/WildcardMatcher.java b/common/src/main/java/org/opensearch/security/common/support/WildcardMatcher.java new file mode 100644 index 0000000000..4e5ab5b29b --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/support/WildcardMatcher.java @@ -0,0 +1,556 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.support; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; + +public abstract class WildcardMatcher implements Predicate { + + public static final WildcardMatcher ANY = new WildcardMatcher() { + + @Override + public boolean matchAny(Stream candidates) { + return true; + } + + @Override + public boolean matchAny(Collection candidates) { + return true; + } + + @Override + public boolean matchAny(String... candidates) { + return true; + } + + @Override + public boolean matchAll(Stream candidates) { + return true; + } + + @Override + public boolean matchAll(Collection candidates) { + return true; + } + + @Override + public boolean matchAll(String[] candidates) { + return true; + } + + @Override + public > T getMatchAny(Stream candidates, Collector collector) { + return candidates.collect(collector); + } + + @Override + public boolean test(String candidate) { + return true; + } + + @Override + public String toString() { + return "*"; + } + }; + + public static final WildcardMatcher NONE = new WildcardMatcher() { + + @Override + public boolean matchAny(Stream candidates) { + return false; + } + + @Override + public boolean matchAny(Collection candidates) { + return false; + } + + @Override + public boolean matchAny(String... candidates) { + return false; + } + + @Override + public boolean matchAll(Stream candidates) { + return false; + } + + @Override + public boolean matchAll(Collection candidates) { + return false; + } + + @Override + public boolean matchAll(String[] candidates) { + return false; + } + + @Override + public > T getMatchAny(Stream candidates, Collector collector) { + return Stream.empty().collect(collector); + } + + @Override + public > T getMatchAny(Collection candidate, Collector collector) { + return Stream.empty().collect(collector); + } + + @Override + public > T getMatchAny(String[] candidate, Collector collector) { + return Stream.empty().collect(collector); + } + + @Override + public boolean test(String candidate) { + return false; + } + + @Override + public String toString() { + return ""; + } + }; + + public static WildcardMatcher from(String pattern, boolean caseSensitive) { + if (pattern == null) { + return NONE; + } else if (pattern.equals("*")) { + return ANY; + } else if (pattern.startsWith("/") && pattern.endsWith("/")) { + return new RegexMatcher(pattern, caseSensitive); + } else if (pattern.indexOf('?') >= 0 || pattern.indexOf('*') >= 0) { + return caseSensitive ? new SimpleMatcher(pattern) : new CasefoldingMatcher(pattern, SimpleMatcher::new); + } else { + return caseSensitive ? new Exact(pattern) : new CasefoldingMatcher(pattern, Exact::new); + } + } + + public static WildcardMatcher from(String pattern) { + return from(pattern, true); + } + + // This may in future use more optimized techniques to combine multiple WildcardMatchers in a single automaton + public static WildcardMatcher from(Stream stream, boolean caseSensitive) { + Collection matchers = stream.map(t -> { + if (t == null) { + return NONE; + } else if (t instanceof String) { + return WildcardMatcher.from(((String) t), caseSensitive); + } else if (t instanceof WildcardMatcher) { + return ((WildcardMatcher) t); + } + throw new UnsupportedOperationException("WildcardMatcher can't be constructed from " + t.getClass().getSimpleName()); + }).collect(ImmutableSet.toImmutableSet()); + + if (matchers.isEmpty()) { + return NONE; + } else if (matchers.size() == 1) { + return matchers.stream().findFirst().get(); + } + return new MatcherCombiner(matchers); + } + + public static WildcardMatcher from(Collection collection, boolean caseSensitive) { + if (collection == null || collection.isEmpty()) { + return NONE; + } else if (collection.size() == 1) { + T t = collection.stream().findFirst().get(); + if (t instanceof String) { + return from(((String) t), caseSensitive); + } else if (t instanceof WildcardMatcher) { + return ((WildcardMatcher) t); + } + throw new UnsupportedOperationException("WildcardMatcher can't be constructed from " + t.getClass().getSimpleName()); + } + return from(collection.stream(), caseSensitive); + } + + public static WildcardMatcher from(String[] patterns, boolean caseSensitive) { + if (patterns == null || patterns.length == 0) { + return NONE; + } else if (patterns.length == 1) { + return from(patterns[0], caseSensitive); + } + return from(Arrays.stream(patterns), caseSensitive); + } + + public static WildcardMatcher from(Stream patterns) { + return from(patterns, true); + } + + public static WildcardMatcher from(Collection patterns) { + return from(patterns, true); + } + + public static WildcardMatcher from(String... patterns) { + return from(patterns, true); + } + + public WildcardMatcher concat(Stream matchers) { + return new MatcherCombiner(Stream.concat(matchers, Stream.of(this)).collect(ImmutableSet.toImmutableSet())); + } + + public WildcardMatcher concat(Collection matchers) { + if (matchers.isEmpty()) { + return this; + } + return concat(matchers.stream()); + } + + public WildcardMatcher concat(WildcardMatcher... matchers) { + if (matchers.length == 0) { + return this; + } + return concat(Arrays.stream(matchers)); + } + + public boolean matchAny(Stream candidates) { + return candidates.anyMatch(this); + } + + public boolean matchAny(Collection candidates) { + return matchAny(candidates.stream()); + } + + public boolean matchAny(String... candidates) { + return matchAny(Arrays.stream(candidates)); + } + + public boolean matchAll(Stream candidates) { + return candidates.allMatch(this); + } + + public boolean matchAll(Collection candidates) { + return matchAll(candidates.stream()); + } + + public boolean matchAll(String[] candidates) { + return matchAll(Arrays.stream(candidates)); + } + + public > T getMatchAny(Stream candidates, Collector collector) { + return candidates.filter(this).collect(collector); + } + + public > T getMatchAny(Collection candidate, Collector collector) { + return getMatchAny(candidate.stream(), collector); + } + + public > T getMatchAny(final String[] candidate, Collector collector) { + return getMatchAny(Arrays.stream(candidate), collector); + } + + public Optional findFirst(final String candidate) { + return Optional.ofNullable(test(candidate) ? this : null); + } + + public Iterable iterateMatching(Iterable candidates) { + return iterateMatching(candidates, Function.identity()); + } + + public Iterable iterateMatching(Iterable candidates, Function toStringFunction) { + return new Iterable() { + + @Override + public Iterator iterator() { + Iterator delegate = candidates.iterator(); + + return new Iterator() { + private E next; + + @Override + public boolean hasNext() { + if (next == null) { + init(); + } + + return next != null; + } + + @Override + public E next() { + if (next == null) { + init(); + } + + E result = next; + next = null; + return result; + } + + private void init() { + while (delegate.hasNext()) { + E candidate = delegate.next(); + + if (test(toStringFunction.apply(candidate))) { + next = candidate; + break; + } + } + } + }; + } + }; + } + + public static List matchers(Collection patterns) { + return patterns.stream().map(p -> WildcardMatcher.from(p, true)).collect(Collectors.toList()); + } + + public static List getAllMatchingPatterns(final Collection matchers, final String candidate) { + return matchers.stream().filter(p -> p.test(candidate)).map(Objects::toString).collect(Collectors.toList()); + } + + public static List getAllMatchingPatterns(final Collection pattern, final Collection candidates) { + return pattern.stream().filter(p -> p.matchAny(candidates)).map(Objects::toString).collect(Collectors.toList()); + } + + public static boolean isExact(String pattern) { + return pattern == null || !(pattern.contains("*") || pattern.contains("?") || (pattern.startsWith("/") && pattern.endsWith("/"))); + } + + // + // --- Implementation specializations --- + // + // Casefolding matcher - sits on top of case-sensitive matcher + // and proxies toLower() of input string to the wrapped matcher + private static final class CasefoldingMatcher extends WildcardMatcher { + + private final WildcardMatcher inner; + + public CasefoldingMatcher(String pattern, Function simpleWildcardMatcher) { + this.inner = simpleWildcardMatcher.apply(pattern.toLowerCase()); + } + + @Override + public boolean test(String candidate) { + return inner.test(candidate.toLowerCase()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CasefoldingMatcher that = (CasefoldingMatcher) o; + return inner.equals(that.inner); + } + + @Override + public int hashCode() { + return inner.hashCode(); + } + + @Override + public String toString() { + return inner.toString(); + } + } + + public static final class Exact extends WildcardMatcher { + + private final String pattern; + + private Exact(String pattern) { + this.pattern = pattern; + } + + @Override + public boolean test(String candidate) { + return pattern.equals(candidate); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Exact that = (Exact) o; + return pattern.equals(that.pattern); + } + + @Override + public int hashCode() { + return pattern.hashCode(); + } + + @Override + public String toString() { + return pattern; + } + } + + // RegexMatcher uses JDK Pattern to test for matching, + // assumes "//" strings as input pattern + private static final class RegexMatcher extends WildcardMatcher { + + private final Pattern pattern; + + private RegexMatcher(String pattern, boolean caseSensitive) { + Preconditions.checkArgument(pattern.length() > 1 && pattern.startsWith("/") && pattern.endsWith("/")); + final String stripSlashesPattern = pattern.substring(1, pattern.length() - 1); + this.pattern = caseSensitive + ? Pattern.compile(stripSlashesPattern) + : Pattern.compile(stripSlashesPattern, Pattern.CASE_INSENSITIVE); + } + + @Override + public boolean test(String candidate) { + return pattern.matcher(candidate).matches(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RegexMatcher that = (RegexMatcher) o; + return pattern.pattern().equals(that.pattern.pattern()); + } + + @Override + public int hashCode() { + return pattern.pattern().hashCode(); + } + + @Override + public String toString() { + return "/" + pattern.pattern() + "/"; + } + } + + // Simple implementation of WildcardMatcher matcher with * and ? without + // using exlicit stack or recursion (as long as we don't need sub-matches it does work) + // allows us to save on resources and heap allocations unless Regex is required + private static final class SimpleMatcher extends WildcardMatcher { + + private final String pattern; + + SimpleMatcher(String pattern) { + this.pattern = pattern; + } + + @Override + public boolean test(String candidate) { + int i = 0; + int j = 0; + int n = candidate.length(); + int m = pattern.length(); + int text_backup = -1; + int wild_backup = -1; + while (i < n) { + if (j < m && pattern.charAt(j) == '*') { + text_backup = i; + wild_backup = ++j; + } else if (j < m && (pattern.charAt(j) == '?' || pattern.charAt(j) == candidate.charAt(i))) { + i++; + j++; + } else { + if (wild_backup == -1) return false; + i = ++text_backup; + j = wild_backup; + } + } + while (j < m && pattern.charAt(j) == '*') + j++; + return j >= m; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimpleMatcher that = (SimpleMatcher) o; + return pattern.equals(that.pattern); + } + + @Override + public int hashCode() { + return pattern.hashCode(); + } + + @Override + public String toString() { + return pattern; + } + } + + // MatcherCombiner is a combination of a set of matchers + // matches if any of the set do + // Empty MultiMatcher always returns false + private static final class MatcherCombiner extends WildcardMatcher { + + private final Collection wildcardMatchers; + private final int hashCode; + + MatcherCombiner(Collection wildcardMatchers) { + Preconditions.checkArgument(wildcardMatchers.size() > 1); + this.wildcardMatchers = wildcardMatchers; + hashCode = wildcardMatchers.hashCode(); + } + + @Override + public boolean test(String candidate) { + return wildcardMatchers.stream().anyMatch(m -> m.test(candidate)); + } + + @Override + public Optional findFirst(final String candidate) { + return wildcardMatchers.stream().filter(m -> m.test(candidate)).findFirst(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MatcherCombiner that = (MatcherCombiner) o; + return wildcardMatchers.equals(that.wildcardMatchers); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public String toString() { + return wildcardMatchers.toString(); + } + } +} diff --git a/common/src/main/java/org/opensearch/security/common/user/AuthCredentials.java b/common/src/main/java/org/opensearch/security/common/user/AuthCredentials.java new file mode 100644 index 0000000000..9255b63dba --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/user/AuthCredentials.java @@ -0,0 +1,254 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.user; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.opensearch.OpenSearchSecurityException; + +/** + * AuthCredentials are an abstraction to encapsulate credentials like passwords or generic + * native credentials like GSS tokens. + * + */ +public final class AuthCredentials { + + private static final String DIGEST_ALGORITHM = "SHA-256"; + private final String username; + private byte[] password; + private Object nativeCredentials; + private final Set securityRoles = new HashSet(); + private final Set backendRoles = new HashSet(); + private boolean complete; + private final byte[] internalPasswordHash; + private final Map attributes = new HashMap<>(); + + /** + * Create new credentials with a username and native credentials + * + * @param username The username, must not be null or empty + * @param nativeCredentials Arbitrary credentials (like GSS tokens), must not be null + * @throws IllegalArgumentException if username or nativeCredentials are null or empty + */ + public AuthCredentials(final String username, final Object nativeCredentials) { + this(username, null, nativeCredentials); + + if (nativeCredentials == null) { + throw new IllegalArgumentException("nativeCredentials must not be null or empty"); + } + } + + /** + * Create new credentials with a username and password + * + * @param username The username, must not be null or empty + * @param password The password, must not be null or empty + * @throws IllegalArgumentException if username or password is null or empty + */ + public AuthCredentials(final String username, final byte[] password) { + this(username, password, null); + + if (password == null || password.length == 0) { + throw new IllegalArgumentException("password must not be null or empty"); + } + } + + /** + * Create new credentials with a username, a initial optional set of roles and empty password/native credentials + + * @param username The username, must not be null or empty + * @param backendRoles set of roles this user is a member of + * @throws IllegalArgumentException if username is null or empty + */ + public AuthCredentials(final String username, String... backendRoles) { + this(username, null, null, backendRoles); + } + + /** + * Create new credentials with a username, a initial optional set of roles and empty password/native credentials + * @param username The username, must not be null or empty + * @param securityRoles The internal roles the user has been mapped to + * @param backendRoles set of roles this user is a member of + * @throws IllegalArgumentException if username is null or empty + */ + public AuthCredentials(final String username, List securityRoles, String... backendRoles) { + this(username, null, null, backendRoles); + this.securityRoles.addAll(securityRoles); + } + + private AuthCredentials(final String username, byte[] password, Object nativeCredentials, String... backendRoles) { + super(); + + if (username == null || username.isEmpty()) { + throw new IllegalArgumentException("username must not be null or empty"); + } + + this.username = username; + // make defensive copy + this.password = password == null ? null : Arrays.copyOf(password, password.length); + + if (this.password != null) { + try { + MessageDigest digester = MessageDigest.getInstance(DIGEST_ALGORITHM); + internalPasswordHash = digester.digest(this.password); + } catch (NoSuchAlgorithmException e) { + throw new OpenSearchSecurityException("Unable to digest password", e); + } + } else { + internalPasswordHash = null; + } + + if (password != null) { + Arrays.fill(password, (byte) '\0'); + password = null; + } + + this.nativeCredentials = nativeCredentials; + nativeCredentials = null; + + if (backendRoles != null && backendRoles.length > 0) { + this.backendRoles.addAll(Arrays.asList(backendRoles)); + } + } + + /** + * Wipe password and native credentials + */ + public void clearSecrets() { + if (password != null) { + Arrays.fill(password, (byte) '\0'); + password = null; + } + + nativeCredentials = null; + } + + public String getUsername() { + return username; + } + + /** + * + * @return Defensive copy of the password + */ + public byte[] getPassword() { + // make defensive copy + return password == null ? null : Arrays.copyOf(password, password.length); + } + + public Object getNativeCredentials() { + return nativeCredentials; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(internalPasswordHash); + result = prime * result + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + AuthCredentials other = (AuthCredentials) obj; + if (internalPasswordHash == null + || other.internalPasswordHash == null + || !MessageDigest.isEqual(internalPasswordHash, other.internalPasswordHash)) return false; + if (username == null) { + if (other.username != null) return false; + } else if (!username.equals(other.username)) return false; + return true; + } + + @Override + public String toString() { + return "AuthCredentials [username=" + + username + + ", password empty=" + + (password == null) + + ", nativeCredentials empty=" + + (nativeCredentials == null) + + ",backendRoles=" + + backendRoles + + "]"; + } + + /** + * + * @return Defensive copy of the roles this user is member of. + */ + public Set getBackendRoles() { + return new HashSet(backendRoles); + } + + /** + * + * @return Defensive copy of the security roles this user is member of. + */ + public Set getSecurityRoles() { + return Set.copyOf(securityRoles); + } + + public boolean isComplete() { + return complete; + } + + /** + * If the credentials are complete and no further roundtrips with the originator are due + * then this method must be called so that the authentication flow can proceed. + *

+ * If this credentials are already marked a complete then a call to this method does nothing. + * + * @return this + */ + public AuthCredentials markComplete() { + this.complete = true; + return this; + } + + public void addAttribute(String name, String value) { + if (name != null && !name.isEmpty()) { + this.attributes.put(name, value); + } + } + + public Map getAttributes() { + return Collections.unmodifiableMap(this.attributes); + } +} diff --git a/common/src/main/java/org/opensearch/security/common/user/CustomAttributesAware.java b/common/src/main/java/org/opensearch/security/common/user/CustomAttributesAware.java new file mode 100644 index 0000000000..144bb04002 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/user/CustomAttributesAware.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.user; + +import java.util.Map; + +public interface CustomAttributesAware { + + Map getCustomAttributesMap(); +} diff --git a/common/src/main/java/org/opensearch/security/common/user/User.java b/common/src/main/java/org/opensearch/security/common/user/User.java new file mode 100644 index 0000000000..015ddf7fb1 --- /dev/null +++ b/common/src/main/java/org/opensearch/security/common/user/User.java @@ -0,0 +1,312 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.common.user; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; + +/** + * A authenticated user and attributes associated to them (like roles, tenant, custom attributes) + *

+ * Do not subclass from this class! + */ +public class User implements Serializable, Writeable, CustomAttributesAware { + + public static final User ANONYMOUS = new User( + "opendistro_security_anonymous", + Lists.newArrayList("opendistro_security_anonymous_backendrole"), + null + ); + + // This is a default user that is injected into a transport request when a user info is not present and passive_intertransport_auth is + // enabled. + // This is to be used in scenarios where some of the nodes do not have security enabled, and therefore do not pass any user information + // in threadcontext, yet we need the communication to not break between the nodes. + // Attach the required permissions to either the user or the backend role. + public static final User DEFAULT_TRANSPORT_USER = new User( + "opendistro_security_default_transport_user", + Lists.newArrayList("opendistro_security_default_transport_backendrole"), + null + ); + + private static final long serialVersionUID = -5500938501822658596L; + private final String name; + /** + * roles == backend_roles + */ + private final Set roles = Collections.synchronizedSet(new HashSet()); + private final Set securityRoles = Collections.synchronizedSet(new HashSet()); + private String requestedTenant; + private Map attributes = Collections.synchronizedMap(new HashMap<>()); + private boolean isInjected = false; + + public User(final StreamInput in) throws IOException { + super(); + name = in.readString(); + roles.addAll(in.readList(StreamInput::readString)); + requestedTenant = in.readString(); + if (requestedTenant.isEmpty()) { + requestedTenant = null; + } + attributes = Collections.synchronizedMap(in.readMap(StreamInput::readString, StreamInput::readString)); + securityRoles.addAll(in.readList(StreamInput::readString)); + } + + /** + * Create a new authenticated user + * + * @param name The username (must not be null or empty) + * @param roles Roles of which the user is a member off (maybe null) + * @param customAttributes Custom attributes associated with this (maybe null) + * @throws IllegalArgumentException if name is null or empty + */ + public User(final String name, final Collection roles, final AuthCredentials customAttributes) { + super(); + + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("name must not be null or empty"); + } + + this.name = name; + + if (roles != null) { + this.addRoles(roles); + } + + if (customAttributes != null) { + this.attributes.putAll(customAttributes.getAttributes()); + } + + } + + /** + * Create a new authenticated user without roles and attributes + * + * @param name The username (must not be null or empty) + * @throws IllegalArgumentException if name is null or empty + */ + public User(final String name) { + this(name, null, null); + } + + public final String getName() { + return name; + } + + /** + * @return A unmodifiable set of the backend roles this user is a member of + */ + public final Set getRoles() { + return Collections.unmodifiableSet(roles); + } + + /** + * Associate this user with a backend role + * + * @param role The backend role + */ + public final void addRole(final String role) { + this.roles.add(role); + } + + /** + * Associate this user with a set of backend roles + * + * @param roles The backend roles + */ + public final void addRoles(final Collection roles) { + if (roles != null) { + this.roles.addAll(roles); + } + } + + /** + * Check if this user is a member of a backend role + * + * @param role The backend role + * @return true if this user is a member of the backend role, false otherwise + */ + public final boolean isUserInRole(final String role) { + return this.roles.contains(role); + } + + /** + * Associate this user with a set of custom attributes + * + * @param attributes custom attributes + */ + public final void addAttributes(final Map attributes) { + if (attributes != null) { + this.attributes.putAll(attributes); + } + } + + public final String getRequestedTenant() { + return requestedTenant; + } + + public final void setRequestedTenant(String requestedTenant) { + this.requestedTenant = requestedTenant; + } + + public boolean isInjected() { + return isInjected; + } + + public void setInjected(boolean isInjected) { + this.isInjected = isInjected; + } + + public final String toStringWithAttributes() { + return "User [name=" + + name + + ", backend_roles=" + + roles + + ", requestedTenant=" + + requestedTenant + + ", attributes=" + + attributes + + "]"; + } + + @Override + public final String toString() { + return "User [name=" + name + ", backend_roles=" + roles + ", requestedTenant=" + requestedTenant + "]"; + } + + @Override + public final int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (name == null ? 0 : name.hashCode()); + return result; + } + + @Override + public final boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof User)) { + return false; + } + final User other = (User) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + + /** + * Copy all backend roles from another user + * + * @param user The user from which the backend roles should be copied over + */ + public final void copyRolesFrom(final User user) { + if (user != null) { + this.addRoles(user.getRoles()); + } + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeStringCollection(new ArrayList(roles)); + out.writeString(requestedTenant == null ? "" : requestedTenant); + out.writeMap(attributes, StreamOutput::writeString, StreamOutput::writeString); + out.writeStringCollection(securityRoles == null ? Collections.emptyList() : new ArrayList(securityRoles)); + } + + /** + * Get the custom attributes associated with this user + * + * @return A modifiable map with all the current custom attributes associated with this user + */ + public synchronized final Map getCustomAttributesMap() { + if (attributes == null) { + attributes = Collections.synchronizedMap(new HashMap<>()); + } + return attributes; + } + + public final void addSecurityRoles(final Collection securityRoles) { + if (securityRoles != null && this.securityRoles != null) { + this.securityRoles.addAll(securityRoles); + } + } + + public final Set getSecurityRoles() { + return this.securityRoles == null + ? Collections.synchronizedSet(Collections.emptySet()) + : Collections.unmodifiableSet(this.securityRoles); + } + + /** + * Check the custom attributes associated with this user + * + * @return true if it has a service account attributes, otherwise false + */ + public boolean isServiceAccount() { + Map userAttributesMap = this.getCustomAttributesMap(); + return userAttributesMap != null && "true".equals(userAttributesMap.get("attr.internal.service")); + } + + /** + * Check the custom attributes associated with this user + * + * @return true if it has a plugin account attributes, otherwise false + */ + public boolean isPluginUser() { + return name != null && name.startsWith("plugin:"); + } + + public void setAttributes(Map attributes) { + if (attributes == null) { + this.attributes = Collections.synchronizedMap(new HashMap<>()); + } + } +} diff --git a/scripts/build.sh b/scripts/build.sh index c4476731f5..e0fa495845 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -79,6 +79,8 @@ cp ${distributions}/*.zip ./$OUTPUT/plugins # Publish jars ./gradlew :opensearch-resource-sharing-spi:publishToMavenLocal -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER +./gradlew :opensearch-security-common:publishToMavenLocal -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER +./gradlew :opensearch-security-client:publishToMavenLocal -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER ./gradlew publishAllPublicationsToStagingRepository -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER ./gradlew publishPluginZipPublicationToZipStagingRepository -Dopensearch.version=$VERSION -Dbuild.snapshot=$SNAPSHOT -Dbuild.version_qualifier=$QUALIFIER diff --git a/settings.gradle b/settings.gradle index 193587dee7..09be0187cc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,3 +8,9 @@ rootProject.name = 'opensearch-security' include "spi" project(":spi").name = "opensearch-resource-sharing-spi" + +include 'common' +project(":common").name = rootProject.name + "-common" + +include 'client' +project(":client").name = rootProject.name + "-client" diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 843553d971..56fda88a42 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -144,6 +144,16 @@ import org.opensearch.security.auditlog.config.AuditConfig.Filter.FilterEntries; import org.opensearch.security.auditlog.impl.AuditLogImpl; import org.opensearch.security.auth.BackendRegistry; +import org.opensearch.security.common.resources.ResourceAccessHandler; +import org.opensearch.security.common.resources.ResourceIndexListener; +import org.opensearch.security.common.resources.ResourcePluginInfo; +import org.opensearch.security.common.resources.ResourceProvider; +import org.opensearch.security.common.resources.ResourceSharingConstants; +import org.opensearch.security.common.resources.ResourceSharingIndexHandler; +import org.opensearch.security.common.resources.ResourceSharingIndexManagementRepository; +import org.opensearch.security.common.resources.rest.ResourceAccessAction; +import org.opensearch.security.common.resources.rest.ResourceAccessRestAction; +import org.opensearch.security.common.resources.rest.ResourceAccessTransportAction; import org.opensearch.security.compliance.ComplianceIndexingOperationListener; import org.opensearch.security.compliance.ComplianceIndexingOperationListenerImpl; import org.opensearch.security.configuration.AdminDNs; @@ -184,6 +194,9 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.setting.OpensearchDynamicSetting; import org.opensearch.security.setting.TransportPassiveAuthSetting; +import org.opensearch.security.spi.resources.Resource; +import org.opensearch.security.spi.resources.ResourceParser; +import org.opensearch.security.spi.resources.ResourceSharingExtension; import org.opensearch.security.ssl.ExternalSecurityKeyStore; import org.opensearch.security.ssl.OpenSearchSecureSettingsFactory; import org.opensearch.security.ssl.OpenSearchSecuritySSLPlugin; @@ -260,6 +273,7 @@ public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin private volatile RestLayerPrivilegesEvaluator restLayerEvaluator; private volatile ConfigurationRepository cr; private volatile AdminDNs adminDns; + private volatile org.opensearch.security.common.configuration.AdminDNs adminDNsCommon; private volatile ClusterService cs; private volatile AtomicReference localNode = new AtomicReference<>(); private volatile AuditLog auditLog; @@ -277,6 +291,7 @@ public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin private volatile OpensearchDynamicSetting transportPassiveAuthSetting; private volatile PasswordHasher passwordHasher; private volatile DlsFlsBaseContext dlsFlsBaseContext; + private ResourceSharingIndexManagementRepository rmr; public static boolean isActionTraceEnabled() { @@ -667,6 +682,14 @@ public List getRestHandlers( passwordHasher ) ); + + // Adds rest handlers for resource-access-control actions + if (settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + )) { + handlers.add(new ResourceAccessRestAction()); + } log.debug("Added {} rest handler(s)", handlers.size()); } } @@ -694,6 +717,12 @@ public UnaryOperator getRestHandlerWrapper(final ThreadContext thre actions.add(new ActionHandler<>(CertificatesActionType.INSTANCE, TransportCertificatesInfoNodesAction.class)); } actions.add(new ActionHandler<>(WhoAmIAction.INSTANCE, TransportWhoAmIAction.class)); + if (settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + )) { + actions.add(new ActionHandler<>(ResourceAccessAction.INSTANCE, ResourceAccessTransportAction.class)); + } } return actions; } @@ -721,6 +750,18 @@ public void onIndexModule(IndexModule indexModule) { dlsFlsBaseContext ) ); + + // Listening on POST and DELETE operations in resource indices + ResourceIndexListener resourceIndexListener = ResourceIndexListener.getInstance(); + resourceIndexListener.initialize(threadPool, localClient); + if (settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + ) && ResourcePluginInfo.getInstance().getResourceIndices().contains(indexModule.getIndex().getName())) { + indexModule.addIndexOperationListener(resourceIndexListener); + log.info("Security plugin started listening to operations on resource-index {}", indexModule.getIndex().getName()); + } + indexModule.forceQueryCacheProvider((indexSettings, nodeCache) -> new QueryCache() { @Override @@ -1097,6 +1138,7 @@ public Collection createComponents( sslExceptionHandler = new AuditLogSslExceptionHandler(auditLog); adminDns = new AdminDNs(settings); + adminDNsCommon = new org.opensearch.security.common.configuration.AdminDNs(settings); cr = ConfigurationRepository.create(settings, this.configPath, threadPool, localClient, clusterService, auditLog); @@ -1125,6 +1167,17 @@ public Collection createComponents( namedXContentRegistry.get() ); + final var resourceSharingIndex = ResourceSharingConstants.OPENSEARCH_RESOURCE_SHARING_INDEX; + ResourceSharingIndexHandler rsIndexHandler = new ResourceSharingIndexHandler(resourceSharingIndex, localClient, threadPool); + ResourceAccessHandler resourceAccessHandler = new ResourceAccessHandler(threadPool, rsIndexHandler, adminDNsCommon); + resourceAccessHandler.initializeRecipientTypes(); + // Resource Sharing index is enabled by default + boolean isResourceSharingEnabled = settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + ); + rmr = ResourceSharingIndexManagementRepository.create(rsIndexHandler, isResourceSharingEnabled); + dlsFlsBaseContext = new DlsFlsBaseContext(evaluator, threadPool.getThreadContext(), adminDns); if (SSLConfig.isSslOnlyMode()) { @@ -1205,6 +1258,7 @@ public Collection createComponents( } components.add(adminDns); + components.add(adminDNsCommon); components.add(cr); components.add(xffResolver); components.add(backendRegistry); @@ -1214,6 +1268,7 @@ public Collection createComponents( components.add(dcf); components.add(userService); components.add(passwordHasher); + components.add(resourceAccessHandler); components.add(sslSettingsManager); if (isSslCertReloadEnabled(settings) && sslCertificatesHotReloadEnabled(settings)) { @@ -2076,6 +2131,16 @@ public List> getSettings() { // Privileges evaluation settings.add(ActionPrivileges.PRECOMPUTED_PRIVILEGES_MAX_HEAP_SIZE); + + // Resource Sharing + settings.add( + Setting.boolSetting( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT, + Property.NodeScope, + Property.Filtered + ) + ); } return settings; @@ -2099,6 +2164,18 @@ public void onNodeStarted(DiscoveryNode localNode) { if (!SSLConfig.isSslOnlyMode() && !client && !disabled && !useClusterStateToInitSecurityConfig(settings)) { cr.initOnNodeStart(); } + + // rmr will be null when sec plugin is disabled or is in SSLOnly mode, hence rmr will not be instantiated + if (settings != null + && settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + ) + && rmr != null) { + // create resource sharing index if absent + rmr.createResourceSharingIndexIfAbsent(); + } + final Set securityModules = ReflectionHelper.getModulesLoaded(); log.info("{} OpenSearch Security modules loaded so far: {}", securityModules.size(), securityModules); } @@ -2144,7 +2221,11 @@ public Collection getSystemIndexDescriptors(Settings sett ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX ); final SystemIndexDescriptor securityIndexDescriptor = new SystemIndexDescriptor(indexPattern, "Security index"); - return List.of(securityIndexDescriptor); + final SystemIndexDescriptor resourceSharingIndexDescriptor = new SystemIndexDescriptor( + ResourceSharingConstants.OPENSEARCH_RESOURCE_SHARING_INDEX, + "Resource Sharing index" + ); + return List.of(securityIndexDescriptor, resourceSharingIndexDescriptor); } @Override @@ -2206,7 +2287,27 @@ private void tryAddSecurityProvider() { // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings @Override public void loadExtensions(ExtensiblePlugin.ExtensionLoader loader) { - // Resource Sharing extensions will be loaded here + + if (settings.getAsBoolean( + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, + ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT + )) { + Set resourceIndices = new HashSet<>(); + Map resourceProviders = new HashMap<>(); + for (ResourceSharingExtension extension : loader.loadExtensions(ResourceSharingExtension.class)) { + String resourceType = extension.getResourceType(); + String resourceIndexName = extension.getResourceIndex(); + ResourceParser resourceParser = extension.getResourceParser(); + + resourceIndices.add(resourceIndexName); + + ResourceProvider resourceProvider = new ResourceProvider(resourceType, resourceIndexName, resourceParser); + resourceProviders.put(resourceIndexName, resourceProvider); + log.info("Loaded resource sharing extension: {}, index: {}", resourceType, resourceIndexName); + } + ResourcePluginInfo.getInstance().setResourceIndices(resourceIndices); + ResourcePluginInfo.getInstance().setResourceProviders(resourceProviders); + } } // CS-ENFORCE-SINGLE diff --git a/src/main/java/org/opensearch/security/auth/BackendRegistry.java b/src/main/java/org/opensearch/security/auth/BackendRegistry.java index 8d47017664..a8295a410f 100644 --- a/src/main/java/org/opensearch/security/auth/BackendRegistry.java +++ b/src/main/java/org/opensearch/security/auth/BackendRegistry.java @@ -58,6 +58,7 @@ import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auth.blocking.ClientBlockRegistry; import org.opensearch.security.auth.internal.NoOpAuthenticationBackend; +import org.opensearch.security.common.auth.UserSubjectImpl; import org.opensearch.security.configuration.AdminDNs; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestChannel; @@ -197,7 +198,7 @@ public void onDynamicConfigModelChanged(DynamicConfigModel dcm) { * @param request * @return The authenticated user, null means another roundtrip * @throws OpenSearchSecurityException - */ + */ public boolean authenticate(final SecurityRequestChannel request) { final boolean isDebugEnabled = log.isDebugEnabled(); final boolean isBlockedBasedOnAddress = request.getRemoteAddress() @@ -224,7 +225,7 @@ public boolean authenticate(final SecurityRequestChannel request) { if (adminDns.isAdminDN(sslPrincipal)) { // PKI authenticated REST call User superuser = new User(sslPrincipal); - UserSubject subject = new UserSubjectImpl(threadPool, superuser); + UserSubject subject = new UserSubjectImpl(threadPool, new org.opensearch.security.common.user.User(sslPrincipal)); threadContext.putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject); threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, superuser); return true; @@ -391,8 +392,15 @@ public boolean authenticate(final SecurityRequestChannel request) { final User impersonatedUser = impersonate(request, authenticatedUser); final User effectiveUser = impersonatedUser == null ? authenticatedUser : impersonatedUser; threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, effectiveUser); - threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INITIATING_USER, authenticatedUser.getName()); - UserSubject subject = new UserSubjectImpl(threadPool, effectiveUser); + + // TODO: The following artistry must be reverted when User class is completely moved to :opensearch-security-common + org.opensearch.security.common.user.User effUser = new org.opensearch.security.common.user.User( + effectiveUser.getName(), + effectiveUser.getRoles(), + null + ); + effUser.setAttributes(effectiveUser.getCustomAttributesMap()); + UserSubject subject = new UserSubjectImpl(threadPool, effUser); threadPool.getThreadContext().putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject); } else { if (isDebugEnabled) { @@ -420,7 +428,14 @@ public boolean authenticate(final SecurityRequestChannel request) { User anonymousUser = new User(User.ANONYMOUS.getName(), new HashSet(User.ANONYMOUS.getRoles()), null); anonymousUser.setRequestedTenant(tenant); - UserSubject subject = new UserSubjectImpl(threadPool, anonymousUser); + org.opensearch.security.common.user.User anonymousUserCommon = new org.opensearch.security.common.user.User( + User.ANONYMOUS.getName(), + new HashSet<>(User.ANONYMOUS.getRoles()), + null + ); + anonymousUserCommon.setRequestedTenant(tenant); + + UserSubject subject = new UserSubjectImpl(threadPool, anonymousUserCommon); threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, anonymousUser); threadPool.getThreadContext().putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject); diff --git a/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java b/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java index 81b813e8b1..58d6f77d0b 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java +++ b/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java @@ -69,6 +69,8 @@ public class Utils { public final static String OPENDISTRO_API_DEPRECATION_MESSAGE = "[_opendistro/_security] is a deprecated endpoint path. Please use _plugins/_security instead."; + public final static String PLUGIN_RESOURCE_ROUTE_PREFIX = PLUGIN_ROUTE_PREFIX + "/resources"; + private static final ObjectMapper internalMapper = new ObjectMapper(); public static Map convertJsonToxToStructuredMap(ToXContent jsonContent) { diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index 633b85cff6..346437e775 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -382,6 +382,10 @@ public enum RolesMappingResolution { // Variable for initial admin password support public static final String OPENSEARCH_INITIAL_ADMIN_PASSWORD = "OPENSEARCH_INITIAL_ADMIN_PASSWORD"; + // Resource sharing feature-flag + public static final String OPENSEARCH_RESOURCE_SHARING_ENABLED = SECURITY_SETTINGS_PREFIX + "resource_sharing.enabled"; + public static final boolean OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT = true; + public static Set getSettingAsSet( final Settings settings, final String key, diff --git a/src/test/java/org/opensearch/security/IndexIntegrationTests.java b/src/test/java/org/opensearch/security/IndexIntegrationTests.java index 31db353c63..91a92ab97d 100644 --- a/src/test/java/org/opensearch/security/IndexIntegrationTests.java +++ b/src/test/java/org/opensearch/security/IndexIntegrationTests.java @@ -846,19 +846,16 @@ public void testIndexResolveMinus() throws Exception { resc = rh.executeGetRequest("/*,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); assertThat(resc.getStatusCode(), is(HttpStatus.SC_FORBIDDEN)); - resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); + resc = rh.executeGetRequest("/*,-*security,-*resource*/_search", encodeBasicHeader("foo_all", "nagilum")); assertThat(resc.getStatusCode(), is(HttpStatus.SC_OK)); - resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); + resc = rh.executeGetRequest("/*,-*security,-foo*,-*resource*/_search", encodeBasicHeader("foo_all", "nagilum")); assertThat(resc.getStatusCode(), is(HttpStatus.SC_OK)); - resc = rh.executeGetRequest("/*,-*security,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); - assertThat(resc.getStatusCode(), is(HttpStatus.SC_OK)); - - resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); + resc = rh.executeGetRequest("/_all,-*security,-*resource*/_search", encodeBasicHeader("foo_all", "nagilum")); assertThat(resc.getStatusCode(), is(HttpStatus.SC_FORBIDDEN)); - resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("nagilum", "nagilum")); + resc = rh.executeGetRequest("/_all,-*security,-*resource*/_search", encodeBasicHeader("nagilum", "nagilum")); assertThat(resc.getStatusCode(), is(HttpStatus.SC_BAD_REQUEST)); } diff --git a/src/test/java/org/opensearch/security/SlowIntegrationTests.java b/src/test/java/org/opensearch/security/SlowIntegrationTests.java index 74e3bfa9e4..99ac9fb1b9 100644 --- a/src/test/java/org/opensearch/security/SlowIntegrationTests.java +++ b/src/test/java/org/opensearch/security/SlowIntegrationTests.java @@ -66,6 +66,7 @@ public void testCustomInterclusterRequestEvaluator() throws Exception { ConfigConstants.SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS, "org.opensearch.security.AlwaysFalseInterClusterRequestEvaluator" ) + .put(ConfigConstants.OPENSEARCH_RESOURCE_SHARING_ENABLED, false) .put("discovery.initial_state_timeout", "8s") .build(); setup(Settings.EMPTY, null, settings, false, ClusterConfiguration.DEFAULT, 5, 1); diff --git a/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java b/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java index 9e630ef750..07bac9e349 100644 --- a/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java +++ b/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java @@ -15,7 +15,8 @@ import org.junit.Test; -import org.opensearch.security.user.User; +import org.opensearch.security.common.auth.UserSubjectImpl; +import org.opensearch.security.common.user.User; import org.opensearch.threadpool.TestThreadPool; import org.opensearch.threadpool.ThreadPool; From db6039851f06fee9afa584fe81b36100d4f71e77 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 17 Mar 2025 19:38:36 -0400 Subject: [PATCH 3/4] Removes redundant files between common and root package Signed-off-by: Darshit Chanpura --- .../common/{ => dlic/rest}/support/Utils.java | 6 +- .../ResourceSharingIndexHandler.java | 2 +- .../rest/ResourceAccessRestAction.java | 4 +- .../{ => support}/DefaultObjectMapper.java | 2 +- .../EncryptionInTransitMigrationTests.java | 2 +- .../IpBruteForceAttacksPreventionTests.java | 2 +- ...cksPreventionWithDomainChallengeTests.java | 2 +- .../security/SearchOperationTest.java | 2 +- .../SecurityConfigurationBootstrapTests.java | 12 +- .../security/SecurityConfigurationTests.java | 4 +- .../org/opensearch/security/SslOnlyTests.java | 2 +- .../opensearch/security/ThreadPoolTests.java | 2 +- .../org/opensearch/security/TlsTests.java | 2 +- .../api/AbstractApiIntegrationTest.java | 6 +- ...bstractConfigEntityApiIntegrationTest.java | 2 +- .../CertificatesRestApiIntegrationTest.java | 2 +- .../api/ConfigRestApiIntegrationTest.java | 6 +- .../security/api/CreateResetPasswordTest.java | 6 +- .../api/DashboardsInfoWithSettingsTest.java | 2 +- ...xpPasswordRulesRestApiIntegrationTest.java | 2 +- .../InternalUsersRestApiIntegrationTest.java | 2 +- ...edPasswordRulesRestApiIntegrationTest.java | 2 +- .../RolesMappingRestApiIntegrationTest.java | 2 +- .../api/RolesRestApiIntegrationTest.java | 2 +- .../api/SslCertsRestApiIntegrationTest.java | 2 +- .../hash/BCryptCustomConfigHashingTests.java | 2 +- .../hash/BCryptDefaultConfigHashingTests.java | 2 +- .../hash/PBKDF2CustomConfigHashingTests.java | 2 +- .../hash/PBKDF2DefaultConfigHashingTests.java | 2 +- .../opensearch/security/http/AsyncTests.java | 2 +- .../security/http/LdapAuthenticationTest.java | 6 +- .../http/OnBehalfOfJwtAuthenticationTest.java | 6 +- .../ServiceAccountAuthenticationTest.java | 8 +- .../privileges/ActionPrivilegesTest.java | 2 +- .../security/privileges/IndexPatternTest.java | 4 +- .../RestEndpointPermissionTests.java | 4 +- .../dlsfls/DlsFlsLegacyHeadersTest.java | 4 +- .../dlsfls/DocumentPrivilegesTest.java | 2 +- .../privileges/dlsfls/FieldMaskingTest.java | 4 +- .../dlsfls/FieldPrivilegesTest.java | 4 +- .../security/rest/AuthZinRestLayerTests.java | 8 +- .../opensearch/security/rest/WhoAmITests.java | 4 +- .../systemindex/SystemIndexDisabledTests.java | 4 +- .../systemindex/SystemIndexTests.java | 4 +- .../test/framework/TestSecurityConfig.java | 2 +- .../audit/AuditMessagePredicate.java | 8 +- .../test/framework/cluster/LocalCluster.java | 2 +- ...inimumSecuritySettingsSupplierFactory.java | 2 +- .../framework/cluster/TestRestClient.java | 2 +- .../testplugins/dummy/LegacyRestHandler.java | 2 +- .../ProtectedRoutesRestHandler.java | 2 +- .../jwt/AbstractHTTPJwtAuthenticator.java | 2 +- .../auth/http/jwt/HTTPJwtAuthenticator.java | 4 +- .../http/jwt/keybyoidc/KeySetRetriever.java | 2 +- .../kerberos/HTTPSpnegoAuthenticator.java | 2 +- .../http/saml/AuthTokenProcessorHandler.java | 2 +- .../auth/http/saml/HTTPSamlAuthenticator.java | 4 +- .../com/amazon/dlic/auth/ldap/LdapUser.java | 6 +- .../backend/LDAPAuthenticationBackend.java | 6 +- .../backend/LDAPAuthorizationBackend.java | 6 +- .../ldap2/LDAPAuthenticationBackend2.java | 6 +- .../auth/ldap2/LDAPAuthorizationBackend2.java | 6 +- .../security/DefaultObjectMapper.java | 298 ---------- .../security/OpenSearchSecurityPlugin.java | 18 +- .../onbehalf/CreateOnBehalfOfTokenAction.java | 4 +- .../action/whoami/TransportWhoAmIAction.java | 6 +- .../security/auditlog/config/AuditConfig.java | 14 +- .../auditlog/config/ThreadPoolConfig.java | 2 +- .../auditlog/impl/AbstractAuditLog.java | 9 +- .../security/auditlog/impl/AuditCategory.java | 40 -- .../security/auditlog/impl/AuditMessage.java | 5 +- .../auditlog/impl/RequestResolver.java | 5 +- .../auditlog/routing/AuditMessageRouter.java | 6 +- .../sink/AbstractInternalOpenSearchSink.java | 2 +- .../security/auditlog/sink/AuditLogSink.java | 2 +- .../auditlog/sink/ExternalOpenSearchSink.java | 2 +- .../InternalOpenSearchDataStreamSink.java | 2 +- .../auditlog/sink/InternalOpenSearchSink.java | 2 +- .../security/auditlog/sink/SinkProvider.java | 4 +- .../security/auditlog/sink/WebhookSink.java | 2 +- .../security/auth/AuthFailureListener.java | 2 +- .../security/auth/AuthenticationBackend.java | 4 +- .../security/auth/AuthorizationBackend.java | 4 +- .../security/auth/BackendRegistry.java | 8 +- .../security/auth/HTTPAuthenticator.java | 2 +- .../security/auth/RolesInjector.java | 4 +- .../security/auth/UserInjector.java | 4 +- .../InternalAuthenticationBackend.java | 4 +- .../internal/NoOpAuthenticationBackend.java | 4 +- .../internal/NoOpAuthorizationBackend.java | 4 +- .../auth/limiting/AbstractRateLimiter.java | 2 +- .../limiting/AddressBasedRateLimiter.java | 2 +- .../limiting/UserNameBasedRateLimiter.java | 2 +- .../security/compliance/ComplianceConfig.java | 8 +- .../compliance/FieldReadCallback.java | 2 +- .../security/configuration/AdminDNs.java | 162 ----- .../security/configuration/CompatConfig.java | 4 +- .../ConfigurationLoaderSecurity7.java | 4 +- .../ConfigurationRepository.java | 4 +- .../DlsFilterLevelActionHandler.java | 2 +- .../configuration/DlsFlsFilterLeafReader.java | 2 +- .../configuration/DlsFlsValveImpl.java | 2 +- .../PrivilegesInterceptorImpl.java | 2 +- .../security/configuration/Salt.java | 2 +- .../SecurityFlsDlsIndexSearcherWrapper.java | 3 +- .../SystemIndexSearcherWrapper.java | 7 +- .../dlic/rest/api/AbstractApiAction.java | 20 +- .../dlic/rest/api/AccountApiAction.java | 16 +- .../dlic/rest/api/ActionGroupsApiAction.java | 10 +- .../dlic/rest/api/AllowlistApiAction.java | 2 +- .../dlic/rest/api/AuditApiAction.java | 16 +- .../rest/api/AuthTokenProcessorAction.java | 8 +- .../dlic/rest/api/CertificatesApiAction.java | 8 +- .../dlic/rest/api/ConfigUpgradeApiAction.java | 14 +- .../dlic/rest/api/FlushCacheApiAction.java | 10 +- .../dlic/rest/api/InternalUsersApiAction.java | 18 +- .../rest/api/MultiTenancyConfigApiAction.java | 12 +- .../dlic/rest/api/NodesDnApiAction.java | 10 +- .../dlic/rest/api/PermissionsInfoAction.java | 12 +- .../dlic/rest/api/RateLimitersApiAction.java | 18 +- .../dlic/rest/api/RequestHandler.java | 10 +- .../security/dlic/rest/api/Responses.java | 106 ---- .../api/RestApiAdminPrivilegesEvaluator.java | 10 +- .../rest/api/RestApiPrivilegesEvaluator.java | 8 +- .../dlic/rest/api/RolesApiAction.java | 6 +- .../dlic/rest/api/RolesMappingApiAction.java | 6 +- .../rest/api/SecurityApiDependencies.java | 4 +- .../rest/api/SecurityConfigApiAction.java | 10 +- .../dlic/rest/api/SecurityRestApiActions.java | 4 +- .../rest/api/SecuritySSLCertsApiAction.java | 17 +- .../dlic/rest/api/TenantsApiAction.java | 6 +- .../dlic/rest/api/WhitelistApiAction.java | 2 +- .../security/dlic/rest/support/Utils.java | 285 --------- .../rest/validation/EndpointValidator.java | 8 +- .../rest/validation/PasswordValidator.java | 6 +- .../validation/RequestContentValidator.java | 6 +- .../security/filter/SecurityFilter.java | 8 +- .../security/filter/SecurityRestFilter.java | 8 +- .../hasher/PasswordHasherFactory.java | 6 +- .../security/http/HTTPBasicAuthenticator.java | 2 +- .../http/HTTPClientCertAuthenticator.java | 4 +- .../security/http/HTTPProxyAuthenticator.java | 4 +- .../http/OnBehalfOfAuthenticator.java | 4 +- .../security/http/RemoteIpDetector.java | 2 +- .../opensearch/security/http/XFFResolver.java | 2 +- .../proxy/HTTPExtendedProxyAuthenticator.java | 2 +- .../ContextProvidingPluginSubject.java | 4 +- .../identity/SecurityTokenManager.java | 4 +- .../security/privileges/ActionPrivileges.java | 2 +- .../privileges/DocumentAllowList.java | 2 +- .../security/privileges/IndexPattern.java | 2 +- .../PrivilegesEvaluationContext.java | 4 +- .../privileges/PrivilegesEvaluator.java | 8 +- .../privileges/PrivilegesInterceptor.java | 2 +- .../ProtectedIndexAccessEvaluator.java | 4 +- .../RestLayerPrivilegesEvaluator.java | 2 +- .../privileges/SnapshotRestoreEvaluator.java | 2 +- .../SystemIndexAccessEvaluator.java | 6 +- .../security/privileges/UserAttributes.java | 2 +- .../security/privileges/WellKnownActions.java | 2 +- .../dlsfls/AbstractRuleBasedPrivileges.java | 4 +- .../privileges/dlsfls/DlsFlsBaseContext.java | 6 +- .../dlsfls/DlsFlsLegacyHeaders.java | 2 +- .../privileges/dlsfls/FieldMasking.java | 4 +- .../privileges/dlsfls/FieldPrivileges.java | 2 +- .../resolver/IndexResolverReplacer.java | 2 +- .../security/rest/DashboardsInfoAction.java | 12 +- .../rest/SecurityConfigUpdateAction.java | 14 +- .../security/rest/SecurityHealthAction.java | 10 +- .../security/rest/SecurityInfoAction.java | 14 +- .../security/rest/SecurityWhoAmIAction.java | 8 +- .../security/rest/TenantInfoAction.java | 16 +- .../security/securityconf/ConfigModel.java | 2 +- .../security/securityconf/ConfigModelV7.java | 6 +- .../securityconf/DynamicConfigFactory.java | 6 +- .../security/securityconf/NodesDnModel.java | 2 +- .../impl/SecurityDynamicConfiguration.java | 2 +- .../securityconf/impl/v7/ConfigV7.java | 2 +- .../setting/TransportPassiveAuthSetting.java | 2 +- .../ssl/OpenSearchSecuritySSLPlugin.java | 2 +- .../Netty4HttpRequestHeaderVerifier.java | 2 +- .../security/ssl/transport/SSLConfig.java | 2 +- .../transport/SecuritySSLRequestHandler.java | 2 +- .../security/support/Base64CustomHelper.java | 2 +- .../security/support/ConfigConstants.java | 401 ------------- .../security/support/ConfigHelper.java | 2 +- .../security/support/HTTPHelper.java | 3 +- .../security/support/HeaderHelper.java | 3 +- .../security/support/HostAndCidrMatcher.java | 2 + .../security/support/JsonFlattener.java | 2 +- .../support/SafeSerializationUtils.java | 2 +- .../support/SecurityIndexHandler.java | 3 +- .../security/support/SecurityJsonNode.java | 2 +- .../security/support/SecuritySettings.java | 1 + .../security/support/SecurityUtils.java | 1 + .../security/support/WildcardMatcher.java | 556 ------------------ .../security/support/YamlConfigReader.java | 2 +- .../security/tools/AuditConfigMigrater.java | 2 +- .../org/opensearch/security/tools/Hasher.java | 2 +- .../security/tools/SecurityAdmin.java | 4 +- .../SecuritySettingsConfigurer.java | 4 +- .../DefaultInterClusterRequestEvaluator.java | 4 +- .../transport/OIDClusterRequestEvaluator.java | 2 +- .../transport/SecurityInterceptor.java | 4 +- .../transport/SecurityRequestHandler.java | 4 +- .../security/user/AuthCredentials.java | 254 -------- .../security/user/CustomAttributesAware.java | 34 -- .../org/opensearch/security/user/User.java | 308 ---------- .../opensearch/security/user/UserService.java | 5 +- .../http/jwt/HTTPJwtAuthenticatorTest.java | 2 +- ...wtKeyByOpenIdConnectAuthenticatorTest.java | 2 +- ...wtKeyByOpenIdConnectAuthenticatorTest.java | 2 +- .../http/saml/HTTPSamlAuthenticatorTest.java | 4 +- .../dlic/auth/ldap/LdapBackendIntegTest.java | 2 +- .../dlic/auth/ldap/LdapBackendTest.java | 4 +- .../auth/ldap/LdapBackendTestClientCert.java | 2 +- .../ldap/LdapBackendTestNewStyleConfig.java | 4 +- .../auth/ldap2/LdapBackendIntegTest2.java | 2 +- .../ldap2/LdapBackendTestClientCert2.java | 2 +- .../ldap2/LdapBackendTestNewStyleConfig2.java | 6 +- .../ldap2/LdapBackendTestOldStyleConfig2.java | 6 +- .../AdvancedSecurityMigrationTests.java | 2 +- .../EncryptionInTransitMigrationTests.java | 2 +- .../security/HttpIntegrationTests.java | 4 +- .../security/IndexIntegrationTests.java | 2 +- .../InitializationIntegrationTests.java | 3 +- .../opensearch/security/IntegrationTests.java | 4 +- .../security/RolesInjectorIntegTest.java | 2 +- .../security/RolesValidationIntegTest.java | 2 +- .../security/SecurityAdminTests.java | 2 +- .../security/SecurityRolesTests.java | 2 +- .../security/SlowIntegrationTests.java | 2 +- .../security/SystemIntegratorsTests.java | 2 +- .../org/opensearch/security/TracingTests.java | 2 +- .../TransportUserInjectorIntegTest.java | 2 +- .../security/UserServiceUnitTests.java | 2 +- .../org/opensearch/security/UtilTests.java | 4 +- .../auditlog/AbstractAuditlogUnitTest.java | 2 +- .../compliance/ComplianceAuditlogTest.java | 4 +- .../compliance/ComplianceConfigTest.java | 4 +- .../RestApiComplianceAuditlogTest.java | 4 +- .../config/AuditConfigFilterTest.java | 18 +- .../config/AuditConfigSerializeTest.java | 10 +- .../helper/MockAuditMessageFactory.java | 2 +- .../auditlog/impl/AuditCategoryTest.java | 6 +- .../auditlog/impl/AuditMessageTest.java | 1 + .../security/auditlog/impl/AuditlogTest.java | 3 +- .../auditlog/impl/DisabledCategoriesTest.java | 3 +- .../auditlog/impl/IgnoreAuditUsersTest.java | 4 +- .../security/auditlog/impl/TracingTests.java | 2 +- .../integration/BasicAuditlogTest.java | 4 +- .../auditlog/integration/SSLAuditlogTest.java | 2 +- .../auditlog/routing/FallbackTest.java | 4 +- .../security/auditlog/routing/PerfTest.java | 4 +- .../security/auditlog/routing/RouterTest.java | 4 +- .../routing/RoutingConfigurationTest.java | 2 +- .../InternalOpensearchDataStreamSinkTest.java | 2 +- .../security/auditlog/sink/KafkaSinkTest.java | 2 +- .../auditlog/sink/SinkProviderTLSTest.java | 2 +- .../auditlog/sink/WebhookAuditLogTest.java | 4 +- .../auth/InternalAuthBackendTests.java | 4 +- .../security/auth/RolesInjectorTest.java | 6 +- .../security/auth/UserInjectorTest.java | 4 +- .../security/auth/UserSubjectImplTests.java | 2 +- .../UserNameBasedRateLimiterTest.java | 2 +- .../security/authtoken/jwt/JwtVendorTest.java | 2 +- .../cache/DummyAuthenticationBackend.java | 4 +- .../security/cache/DummyAuthorizer.java | 4 +- .../cache/DummyHTTPAuthenticator.java | 2 +- .../ccstest/CrossClusterSearchTests.java | 2 +- .../ConfigurationRepositoryTest.java | 6 +- .../security/configuration/SaltTest.java | 2 +- .../dlic/dlsfls/AbstractDlsFlsTest.java | 2 +- .../dlic/dlsfls/CCReplicationTest.java | 2 +- .../dlic/dlsfls/CustomFieldMaskedTest.java | 2 +- .../dlic/dlsfls/DfmOverwritesAllTest.java | 2 +- .../security/dlic/dlsfls/DlsDateMathTest.java | 2 +- .../security/dlic/dlsfls/FieldMaskedTest.java | 2 +- .../api/AbstractApiActionValidationTest.java | 4 +- .../rest/api/AbstractRestApiUnitTest.java | 4 +- .../dlic/rest/api/AllowlistApiTest.java | 8 +- ...tApiActionRequestContentValidatorTest.java | 4 +- .../dlic/rest/api/AuditApiActionTest.java | 6 +- .../api/ConfigUpgradeApiActionUnitTest.java | 4 +- .../rest/api/GetConfigurationApiTest.java | 2 +- .../dlic/rest/api/IndexMissingTest.java | 2 +- .../InternalUsersApiActionValidationTest.java | 4 +- .../rest/api/MultiTenancyConfigApiTest.java | 2 +- .../dlic/rest/api/NodesDnApiTest.java | 6 +- .../RateLimitersApiActionValidationTest.java | 2 +- .../rest/api/RequestHandlersBuilderTest.java | 2 +- .../api/RestApiPrivilegesEvaluatorTest.java | 2 +- .../dlic/rest/api/RoleBasedAccessTest.java | 2 +- ...SecurityConfigApiActionValidationTest.java | 4 +- .../rest/api/SecurityConfigurationTest.java | 2 +- .../dlic/rest/api/TenantInfoActionTest.java | 2 +- .../dlic/rest/api/WhitelistApiTest.java | 6 +- .../validation/EndpointValidatorTest.java | 2 +- .../validation/PasswordValidatorTest.java | 6 +- .../RequestContentValidatorTest.java | 2 +- .../security/filter/SecurityFilterTests.java | 6 +- .../filter/SecurityRestFilterUnitTests.java | 2 +- .../hasher/BCryptPasswordHasherTests.java | 2 +- .../hasher/PBKDF2PasswordHasherTests.java | 2 +- .../hasher/PasswordHasherFactoryTests.java | 2 +- .../http/OnBehalfOfAuthenticatorTest.java | 2 +- .../HTTPExtendedProxyAuthenticatorTest.java | 4 +- .../ContextProvidingPluginSubjectTests.java | 4 +- .../identity/SecurityTokenManagerTest.java | 4 +- .../multitenancy/test/MultitenancyTests.java | 6 +- .../RestLayerPrivilegesEvaluatorTest.java | 2 +- .../SystemIndexAccessEvaluatorTest.java | 6 +- .../ProtectedIndicesTests.java | 2 +- .../SecurityDynamicConfigurationTest.java | 2 +- .../securityconf/impl/v7/ConfigV7Test.java | 2 +- .../opensearch/security/ssl/OpenSSLTest.java | 2 +- .../org/opensearch/security/ssl/SSLTest.java | 2 +- .../SecuritySSLReloadCertsActionTests.java | 4 +- .../security/ssl/SslSettingsManagerTest.java | 2 +- .../support/Base64CustomHelperTest.java | 5 +- .../security/support/Base64JDKHelperTest.java | 5 +- .../security/support/ConfigReaderTest.java | 2 +- .../support/SafeSerializationUtilsTest.java | 2 +- .../support/SecurityIndexHandlerTest.java | 2 +- .../AbstractSystemIndicesTests.java | 2 +- .../test/AbstractSecurityUnitTest.java | 4 +- .../security/test/helper/rest/RestHelper.java | 2 +- .../SecuritySettingsConfigurerTests.java | 2 +- .../transport/SecurityInterceptorTests.java | 4 +- .../SecuritySSLRequestHandlerTests.java | 2 +- 330 files changed, 676 insertions(+), 3096 deletions(-) rename common/src/main/java/org/opensearch/security/common/{ => dlic/rest}/support/Utils.java (98%) rename common/src/main/java/org/opensearch/security/common/{ => support}/DefaultObjectMapper.java (99%) delete mode 100644 src/main/java/org/opensearch/security/DefaultObjectMapper.java delete mode 100644 src/main/java/org/opensearch/security/auditlog/impl/AuditCategory.java delete mode 100644 src/main/java/org/opensearch/security/configuration/AdminDNs.java delete mode 100644 src/main/java/org/opensearch/security/dlic/rest/api/Responses.java delete mode 100644 src/main/java/org/opensearch/security/dlic/rest/support/Utils.java delete mode 100644 src/main/java/org/opensearch/security/support/ConfigConstants.java delete mode 100644 src/main/java/org/opensearch/security/support/WildcardMatcher.java delete mode 100644 src/main/java/org/opensearch/security/user/AuthCredentials.java delete mode 100644 src/main/java/org/opensearch/security/user/CustomAttributesAware.java delete mode 100644 src/main/java/org/opensearch/security/user/User.java diff --git a/common/src/main/java/org/opensearch/security/common/support/Utils.java b/common/src/main/java/org/opensearch/security/common/dlic/rest/support/Utils.java similarity index 98% rename from common/src/main/java/org/opensearch/security/common/support/Utils.java rename to common/src/main/java/org/opensearch/security/common/dlic/rest/support/Utils.java index ffdc8d9390..6fc2bd35b5 100644 --- a/common/src/main/java/org/opensearch/security/common/support/Utils.java +++ b/common/src/main/java/org/opensearch/security/common/dlic/rest/support/Utils.java @@ -9,7 +9,7 @@ * GitHub history for details. */ -package org.opensearch.security.common.support; +package org.opensearch.security.common.dlic.rest.support; import java.io.IOException; import java.io.UncheckedIOException; @@ -46,12 +46,14 @@ import org.opensearch.rest.NamedRoute; import org.opensearch.rest.RestHandler.DeprecatedRoute; import org.opensearch.rest.RestHandler.Route; -import org.opensearch.security.common.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.common.user.User; import static org.opensearch.core.xcontent.DeprecationHandler.THROW_UNSUPPORTED_OPERATION; public class Utils { + @Deprecated public static final String LEGACY_OPENDISTRO_PREFIX = "_opendistro/_security"; public static final String PLUGINS_PREFIX = "_plugins/_security"; diff --git a/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java index 8ff771d74e..3ce681031e 100644 --- a/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java +++ b/common/src/main/java/org/opensearch/security/common/resources/ResourceSharingIndexHandler.java @@ -63,7 +63,7 @@ import org.opensearch.search.Scroll; import org.opensearch.search.SearchHit; import org.opensearch.search.builder.SearchSourceBuilder; -import org.opensearch.security.common.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.spi.resources.Resource; import org.opensearch.security.spi.resources.ResourceParser; import org.opensearch.security.spi.resources.exceptions.ResourceSharingException; diff --git a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java index 700a064ed5..7b66a239f9 100644 --- a/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java +++ b/common/src/main/java/org/opensearch/security/common/resources/rest/ResourceAccessRestAction.java @@ -32,12 +32,12 @@ import static org.opensearch.security.common.dlic.rest.api.Responses.forbidden; import static org.opensearch.security.common.dlic.rest.api.Responses.ok; import static org.opensearch.security.common.dlic.rest.api.Responses.unauthorized; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_RESOURCE_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.LIST; import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.REVOKE; import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.SHARE; import static org.opensearch.security.common.resources.rest.ResourceAccessRequest.Operation.VERIFY; -import static org.opensearch.security.common.support.Utils.PLUGIN_RESOURCE_ROUTE_PREFIX; -import static org.opensearch.security.common.support.Utils.addRoutesPrefix; /** * This class handles the REST API for resource access management. diff --git a/common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java b/common/src/main/java/org/opensearch/security/common/support/DefaultObjectMapper.java similarity index 99% rename from common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java rename to common/src/main/java/org/opensearch/security/common/support/DefaultObjectMapper.java index 7a2dc137a6..01da1bde16 100644 --- a/common/src/main/java/org/opensearch/security/common/DefaultObjectMapper.java +++ b/common/src/main/java/org/opensearch/security/common/support/DefaultObjectMapper.java @@ -24,7 +24,7 @@ * GitHub history for details. */ -package org.opensearch.security.common; +package org.opensearch.security.common.support; import java.io.IOException; import java.security.AccessController; diff --git a/src/integrationTest/java/org/opensearch/security/EncryptionInTransitMigrationTests.java b/src/integrationTest/java/org/opensearch/security/EncryptionInTransitMigrationTests.java index 58eb7218e6..a5cf4b04a5 100644 --- a/src/integrationTest/java/org/opensearch/security/EncryptionInTransitMigrationTests.java +++ b/src/integrationTest/java/org/opensearch/security/EncryptionInTransitMigrationTests.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; import org.opensearch.test.framework.cluster.TestRestClient; diff --git a/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionTests.java b/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionTests.java index 45ce33a346..5db6cf4003 100644 --- a/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionTests.java +++ b/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionTests.java @@ -33,7 +33,7 @@ import static org.opensearch.security.api.AbstractApiIntegrationTest.configJsonArray; import static org.opensearch.security.api.PatchPayloadHelper.patch; import static org.opensearch.security.api.PatchPayloadHelper.replaceOp; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL_WITHOUT_CHALLENGE; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.opensearch.test.framework.cluster.TestRestClientConfiguration.userWithSourceIp; diff --git a/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionWithDomainChallengeTests.java b/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionWithDomainChallengeTests.java index 61d5a651b8..65882def67 100644 --- a/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionWithDomainChallengeTests.java +++ b/src/integrationTest/java/org/opensearch/security/IpBruteForceAttacksPreventionWithDomainChallengeTests.java @@ -18,7 +18,7 @@ import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) diff --git a/src/integrationTest/java/org/opensearch/security/SearchOperationTest.java b/src/integrationTest/java/org/opensearch/security/SearchOperationTest.java index e8e15d1910..81903867d4 100644 --- a/src/integrationTest/java/org/opensearch/security/SearchOperationTest.java +++ b/src/integrationTest/java/org/opensearch/security/SearchOperationTest.java @@ -142,7 +142,7 @@ import static org.opensearch.security.Song.TITLE_NEXT_SONG; import static org.opensearch.security.Song.TITLE_POISON; import static org.opensearch.security.Song.TITLE_SONG_1_PLUS_1; -import static org.opensearch.security.auditlog.impl.AuditCategory.INDEX_EVENT; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.INDEX_EVENT; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.opensearch.test.framework.audit.AuditMessagePredicate.auditPredicate; diff --git a/src/integrationTest/java/org/opensearch/security/SecurityConfigurationBootstrapTests.java b/src/integrationTest/java/org/opensearch/security/SecurityConfigurationBootstrapTests.java index e6af5d58bb..8b9b3f8a34 100644 --- a/src/integrationTest/java/org/opensearch/security/SecurityConfigurationBootstrapTests.java +++ b/src/integrationTest/java/org/opensearch/security/SecurityConfigurationBootstrapTests.java @@ -24,8 +24,8 @@ import org.junit.runner.RunWith; import org.opensearch.action.admin.cluster.health.ClusterHealthRequest; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.ConfigHelper; import org.opensearch.test.framework.TestSecurityConfig.User; import org.opensearch.test.framework.cluster.ClusterManager; @@ -37,12 +37,12 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS; import static org.opensearch.security.configuration.ConfigurationRepository.DEFAULT_CONFIG_VERSION; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) diff --git a/src/integrationTest/java/org/opensearch/security/SecurityConfigurationTests.java b/src/integrationTest/java/org/opensearch/security/SecurityConfigurationTests.java index 0e58f0fe07..510f3aa63c 100644 --- a/src/integrationTest/java/org/opensearch/security/SecurityConfigurationTests.java +++ b/src/integrationTest/java/org/opensearch/security/SecurityConfigurationTests.java @@ -44,8 +44,8 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.opensearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; -import static org.opensearch.security.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; diff --git a/src/integrationTest/java/org/opensearch/security/SslOnlyTests.java b/src/integrationTest/java/org/opensearch/security/SslOnlyTests.java index 2ea5b4c0b2..cc35cffb69 100644 --- a/src/integrationTest/java/org/opensearch/security/SslOnlyTests.java +++ b/src/integrationTest/java/org/opensearch/security/SslOnlyTests.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; import org.opensearch.test.framework.cluster.TestRestClient; diff --git a/src/integrationTest/java/org/opensearch/security/ThreadPoolTests.java b/src/integrationTest/java/org/opensearch/security/ThreadPoolTests.java index 10aaab0f73..43c7ac8b5c 100644 --- a/src/integrationTest/java/org/opensearch/security/ThreadPoolTests.java +++ b/src/integrationTest/java/org/opensearch/security/ThreadPoolTests.java @@ -31,7 +31,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.opensearch.test.framework.TestSecurityConfig.User.USER_ADMIN; diff --git a/src/integrationTest/java/org/opensearch/security/TlsTests.java b/src/integrationTest/java/org/opensearch/security/TlsTests.java index 515d448728..23289072cf 100644 --- a/src/integrationTest/java/org/opensearch/security/TlsTests.java +++ b/src/integrationTest/java/org/opensearch/security/TlsTests.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.test.framework.AuditCompliance; import org.opensearch.test.framework.AuditConfiguration; import org.opensearch.test.framework.AuditFilters; diff --git a/src/integrationTest/java/org/opensearch/security/api/AbstractApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/AbstractApiIntegrationTest.java index a69ca83378..06a4170906 100644 --- a/src/integrationTest/java/org/opensearch/security/api/AbstractApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/AbstractApiIntegrationTest.java @@ -36,11 +36,11 @@ import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.ToXContentObject; import org.opensearch.security.ConfigurationFiles; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.certificate.CertificateData; import org.opensearch.test.framework.cluster.ClusterManager; @@ -57,12 +57,12 @@ import static org.opensearch.security.CrossClusterSearchTests.PLUGINS_SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.RELOAD_CERTS_ACTION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.SECURITY_CONFIG_UPDATE; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; import static org.opensearch.test.framework.TestSecurityConfig.REST_ADMIN_REST_API_ACCESS; @ThreadLeakScope(ThreadLeakScope.Scope.NONE) diff --git a/src/integrationTest/java/org/opensearch/security/api/AbstractConfigEntityApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/AbstractConfigEntityApiIntegrationTest.java index d25ae508c8..98f73c8cc9 100644 --- a/src/integrationTest/java/org/opensearch/security/api/AbstractConfigEntityApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/AbstractConfigEntityApiIntegrationTest.java @@ -34,7 +34,7 @@ import static org.opensearch.security.api.PatchPayloadHelper.patch; import static org.opensearch.security.api.PatchPayloadHelper.removeOp; import static org.opensearch.security.api.PatchPayloadHelper.replaceOp; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public abstract class AbstractConfigEntityApiIntegrationTest extends AbstractApiIntegrationTest { diff --git a/src/integrationTest/java/org/opensearch/security/api/CertificatesRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/CertificatesRestApiIntegrationTest.java index 175eb109e8..539f0eef13 100644 --- a/src/integrationTest/java/org/opensearch/security/api/CertificatesRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/CertificatesRestApiIntegrationTest.java @@ -35,8 +35,8 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class CertificatesRestApiIntegrationTest extends AbstractApiIntegrationTest { diff --git a/src/integrationTest/java/org/opensearch/security/api/ConfigRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/ConfigRestApiIntegrationTest.java index 16b089f99b..40e4f823b7 100644 --- a/src/integrationTest/java/org/opensearch/security/api/ConfigRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/ConfigRestApiIntegrationTest.java @@ -16,15 +16,15 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.test.framework.cluster.TestRestClient; import static org.opensearch.security.api.PatchPayloadHelper.patch; import static org.opensearch.security.api.PatchPayloadHelper.replaceOp; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.SECURITY_CONFIG_UPDATE; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; public class ConfigRestApiIntegrationTest extends AbstractApiIntegrationTest { diff --git a/src/integrationTest/java/org/opensearch/security/api/CreateResetPasswordTest.java b/src/integrationTest/java/org/opensearch/security/api/CreateResetPasswordTest.java index 8a7795e90f..6db16e1324 100644 --- a/src/integrationTest/java/org/opensearch/security/api/CreateResetPasswordTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/CreateResetPasswordTest.java @@ -17,8 +17,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig.User; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; @@ -31,8 +31,8 @@ import static org.opensearch.security.SecurityConfigurationTests.ADDITIONAL_USER_1; import static org.opensearch.security.SecurityConfigurationTests.CREATE_USER_BODY; import static org.opensearch.security.SecurityConfigurationTests.INTERNAL_USERS_RESOURCE; -import static org.opensearch.security.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; diff --git a/src/integrationTest/java/org/opensearch/security/api/DashboardsInfoWithSettingsTest.java b/src/integrationTest/java/org/opensearch/security/api/DashboardsInfoWithSettingsTest.java index af8eeb2c8a..d48ffb3e71 100644 --- a/src/integrationTest/java/org/opensearch/security/api/DashboardsInfoWithSettingsTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/DashboardsInfoWithSettingsTest.java @@ -16,7 +16,7 @@ import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.TestSecurityConfig.Role; diff --git a/src/integrationTest/java/org/opensearch/security/api/InternalUsersRegExpPasswordRulesRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/InternalUsersRegExpPasswordRulesRestApiIntegrationTest.java index 684f30e60b..7c72f590e5 100644 --- a/src/integrationTest/java/org/opensearch/security/api/InternalUsersRegExpPasswordRulesRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/InternalUsersRegExpPasswordRulesRestApiIntegrationTest.java @@ -17,9 +17,9 @@ import org.junit.Test; import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.PasswordValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; -import org.opensearch.security.support.ConfigConstants; import static org.opensearch.security.api.PatchPayloadHelper.addOp; import static org.opensearch.security.api.PatchPayloadHelper.patch; diff --git a/src/integrationTest/java/org/opensearch/security/api/InternalUsersRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/InternalUsersRestApiIntegrationTest.java index 18769949fe..38d2015db4 100644 --- a/src/integrationTest/java/org/opensearch/security/api/InternalUsersRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/InternalUsersRestApiIntegrationTest.java @@ -30,7 +30,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.Strings; import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.TestRestClient; diff --git a/src/integrationTest/java/org/opensearch/security/api/InternalUsersScoreBasedPasswordRulesRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/InternalUsersScoreBasedPasswordRulesRestApiIntegrationTest.java index b18a0c6fd6..668828fa49 100644 --- a/src/integrationTest/java/org/opensearch/security/api/InternalUsersScoreBasedPasswordRulesRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/InternalUsersScoreBasedPasswordRulesRestApiIntegrationTest.java @@ -17,8 +17,8 @@ import org.junit.Test; import org.opensearch.core.xcontent.ToXContentObject; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; -import org.opensearch.security.support.ConfigConstants; import static org.opensearch.security.api.PatchPayloadHelper.addOp; import static org.opensearch.security.api.PatchPayloadHelper.patch; diff --git a/src/integrationTest/java/org/opensearch/security/api/RolesMappingRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/RolesMappingRestApiIntegrationTest.java index ac5e4b21d4..29b56daecc 100644 --- a/src/integrationTest/java/org/opensearch/security/api/RolesMappingRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/RolesMappingRestApiIntegrationTest.java @@ -22,7 +22,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.Strings; import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.TestRestClient; diff --git a/src/integrationTest/java/org/opensearch/security/api/RolesRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/RolesRestApiIntegrationTest.java index f52fe5fbfd..b69798dcd8 100644 --- a/src/integrationTest/java/org/opensearch/security/api/RolesRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/RolesRestApiIntegrationTest.java @@ -23,7 +23,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.Strings; import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.TestRestClient; diff --git a/src/integrationTest/java/org/opensearch/security/api/SslCertsRestApiIntegrationTest.java b/src/integrationTest/java/org/opensearch/security/api/SslCertsRestApiIntegrationTest.java index bbdd9ff793..f45fb6b1c7 100644 --- a/src/integrationTest/java/org/opensearch/security/api/SslCertsRestApiIntegrationTest.java +++ b/src/integrationTest/java/org/opensearch/security/api/SslCertsRestApiIntegrationTest.java @@ -19,8 +19,8 @@ import org.opensearch.test.framework.cluster.TestRestClient; import static org.hamcrest.MatcherAssert.assertThat; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; @Deprecated public class SslCertsRestApiIntegrationTest extends AbstractApiIntegrationTest { diff --git a/src/integrationTest/java/org/opensearch/security/hash/BCryptCustomConfigHashingTests.java b/src/integrationTest/java/org/opensearch/security/hash/BCryptCustomConfigHashingTests.java index 95f05a7c0d..d19926da41 100644 --- a/src/integrationTest/java/org/opensearch/security/hash/BCryptCustomConfigHashingTests.java +++ b/src/integrationTest/java/org/opensearch/security/hash/BCryptCustomConfigHashingTests.java @@ -19,7 +19,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; diff --git a/src/integrationTest/java/org/opensearch/security/hash/BCryptDefaultConfigHashingTests.java b/src/integrationTest/java/org/opensearch/security/hash/BCryptDefaultConfigHashingTests.java index 86adc728ea..3444efea4c 100644 --- a/src/integrationTest/java/org/opensearch/security/hash/BCryptDefaultConfigHashingTests.java +++ b/src/integrationTest/java/org/opensearch/security/hash/BCryptDefaultConfigHashingTests.java @@ -18,7 +18,7 @@ import org.junit.ClassRule; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; diff --git a/src/integrationTest/java/org/opensearch/security/hash/PBKDF2CustomConfigHashingTests.java b/src/integrationTest/java/org/opensearch/security/hash/PBKDF2CustomConfigHashingTests.java index 9f2ceb2e93..2342ce8c17 100644 --- a/src/integrationTest/java/org/opensearch/security/hash/PBKDF2CustomConfigHashingTests.java +++ b/src/integrationTest/java/org/opensearch/security/hash/PBKDF2CustomConfigHashingTests.java @@ -19,7 +19,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; diff --git a/src/integrationTest/java/org/opensearch/security/hash/PBKDF2DefaultConfigHashingTests.java b/src/integrationTest/java/org/opensearch/security/hash/PBKDF2DefaultConfigHashingTests.java index 2becee1f36..ef4a01c97a 100644 --- a/src/integrationTest/java/org/opensearch/security/hash/PBKDF2DefaultConfigHashingTests.java +++ b/src/integrationTest/java/org/opensearch/security/hash/PBKDF2DefaultConfigHashingTests.java @@ -18,7 +18,7 @@ import org.junit.ClassRule; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.ClusterManager; import org.opensearch.test.framework.cluster.LocalCluster; diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index 514d2c45d1..9b109fb78a 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -24,7 +24,7 @@ import org.junit.runner.RunWith; import org.opensearch.security.IndexOperationsHelper; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.AsyncActions; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.cluster.LocalCluster; diff --git a/src/integrationTest/java/org/opensearch/security/http/LdapAuthenticationTest.java b/src/integrationTest/java/org/opensearch/security/http/LdapAuthenticationTest.java index 090762af21..867899e8c5 100644 --- a/src/integrationTest/java/org/opensearch/security/http/LdapAuthenticationTest.java +++ b/src/integrationTest/java/org/opensearch/security/http/LdapAuthenticationTest.java @@ -22,7 +22,7 @@ import org.junit.rules.RuleChain; import org.junit.runner.RunWith; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.AuthorizationBackend; import org.opensearch.test.framework.AuthzDomain; import org.opensearch.test.framework.LdapAuthenticationConfigBuilder; @@ -41,6 +41,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.security.http.CertificateAuthenticationTest.POINTER_BACKEND_ROLES; import static org.opensearch.security.http.DirectoryInformationTrees.CN_GROUP_ADMIN; import static org.opensearch.security.http.DirectoryInformationTrees.DN_CAPTAIN_SPOCK_PEOPLE_TEST_ORG; @@ -55,8 +57,6 @@ import static org.opensearch.security.http.DirectoryInformationTrees.USER_KIRK; import static org.opensearch.security.http.DirectoryInformationTrees.USER_SEARCH; import static org.opensearch.security.http.DirectoryInformationTrees.USER_SPOCK; -import static org.opensearch.security.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.BASIC_AUTH_DOMAIN_ORDER; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; diff --git a/src/integrationTest/java/org/opensearch/security/http/OnBehalfOfJwtAuthenticationTest.java b/src/integrationTest/java/org/opensearch/security/http/OnBehalfOfJwtAuthenticationTest.java index 1dbb10b1f8..7d14952fc7 100644 --- a/src/integrationTest/java/org/opensearch/security/http/OnBehalfOfJwtAuthenticationTest.java +++ b/src/integrationTest/java/org/opensearch/security/http/OnBehalfOfJwtAuthenticationTest.java @@ -47,9 +47,9 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; -import static org.opensearch.security.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; diff --git a/src/integrationTest/java/org/opensearch/security/http/ServiceAccountAuthenticationTest.java b/src/integrationTest/java/org/opensearch/security/http/ServiceAccountAuthenticationTest.java index 932ca71e44..35c7d969ca 100644 --- a/src/integrationTest/java/org/opensearch/security/http/ServiceAccountAuthenticationTest.java +++ b/src/integrationTest/java/org/opensearch/security/http/ServiceAccountAuthenticationTest.java @@ -26,10 +26,10 @@ import org.opensearch.test.framework.cluster.LocalCluster; import org.opensearch.test.framework.cluster.TestRestClient; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_KEY; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SYSTEM_INDICES_KEY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.junit.Assert.assertNotNull; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/ActionPrivilegesTest.java b/src/integrationTest/java/org/opensearch/security/privileges/ActionPrivilegesTest.java index 1f60cf92d5..fe713d88ce 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/ActionPrivilegesTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/ActionPrivilegesTest.java @@ -38,12 +38,12 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.unit.ByteSizeUnit; import org.opensearch.core.common.unit.ByteSizeValue; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.FlattenedActionGroups; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.user.User; import org.opensearch.security.util.MockIndexMetadataBuilder; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/IndexPatternTest.java b/src/integrationTest/java/org/opensearch/security/privileges/IndexPatternTest.java index e098a605e5..2d2eea5429 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/IndexPatternTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/IndexPatternTest.java @@ -22,9 +22,9 @@ import org.opensearch.cluster.metadata.Metadata; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import static org.opensearch.security.util.MockIndexMetadataBuilder.indices; import static org.junit.Assert.assertEquals; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/RestEndpointPermissionTests.java b/src/integrationTest/java/org/opensearch/security/privileges/RestEndpointPermissionTests.java index 1e61aa0206..3238e512f8 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/RestEndpointPermissionTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/RestEndpointPermissionTests.java @@ -43,14 +43,14 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.User; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.PermissionBuilder; import org.opensearch.security.securityconf.FlattenedActionGroups; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.user.User; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeadersTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeadersTest.java index 2c8e6de587..3120bb6417 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeadersTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeadersTest.java @@ -35,12 +35,12 @@ import org.opensearch.index.query.RangeQueryBuilder; import org.opensearch.index.query.TermQueryBuilder; import org.opensearch.search.internal.ShardSearchRequest; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.security.util.MockIndexMetadataBuilder; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.transport.Transport; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DocumentPrivilegesTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DocumentPrivilegesTest.java index 97a0ddb69e..f6527697dc 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DocumentPrivilegesTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/DocumentPrivilegesTest.java @@ -51,13 +51,13 @@ import org.opensearch.index.query.QueryBuilder; import org.opensearch.index.query.QueryBuilders; import org.opensearch.index.query.TermQueryBuilder; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluationException; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.user.User; import org.opensearch.test.framework.TestSecurityConfig; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java index a7ce8b0c1d..204710f62b 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldMaskingTest.java @@ -22,12 +22,12 @@ import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.Metadata; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.test.framework.TestSecurityConfig; import static org.opensearch.security.privileges.dlsfls.FieldMasking.Config.BLAKE2B_LEGACY_DEFAULT; diff --git a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldPrivilegesTest.java b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldPrivilegesTest.java index 54a32e9972..7a4a414a45 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldPrivilegesTest.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/dlsfls/FieldPrivilegesTest.java @@ -21,12 +21,12 @@ import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.Metadata; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.test.framework.TestSecurityConfig; import static org.opensearch.security.util.MockIndexMetadataBuilder.indices; diff --git a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java index 8e0f14baf9..01e5d23f0d 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java @@ -34,10 +34,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.auditlog.impl.AuditCategory.AUTHENTICATED; -import static org.opensearch.security.auditlog.impl.AuditCategory.FAILED_LOGIN; -import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; -import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.AUTHENTICATED; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.FAILED_LOGIN; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateRESTLayer; import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateTransportLayer; diff --git a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java index 9b39320e6c..2b6b1949c9 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java @@ -46,8 +46,8 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.lessThan; import static org.opensearch.rest.RestRequest.Method.GET; -import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; -import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.audit.AuditMessagePredicate.grantedPrivilege; import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateRESTLayer; diff --git a/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexDisabledTests.java b/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexDisabledTests.java index 109e5228cf..2b7f0c3ad2 100644 --- a/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexDisabledTests.java +++ b/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexDisabledTests.java @@ -30,8 +30,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.opensearch.test.framework.TestSecurityConfig.User.USER_ADMIN; diff --git a/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexTests.java b/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexTests.java index e8fdd9d7d4..3404c0fc90 100644 --- a/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexTests.java +++ b/src/integrationTest/java/org/opensearch/security/systemindex/SystemIndexTests.java @@ -32,8 +32,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY; import static org.opensearch.security.systemindex.sampleplugin.SystemIndexPlugin1.SYSTEM_INDEX_1; import static org.opensearch.security.systemindex.sampleplugin.SystemIndexPlugin2.SYSTEM_INDEX_2; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; diff --git a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java index dbe6704e4f..296e8735fa 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java @@ -61,6 +61,7 @@ import org.opensearch.core.xcontent.ToXContentObject; import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.index.query.QueryBuilder; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; import org.opensearch.security.securityconf.impl.CType; @@ -70,7 +71,6 @@ import org.opensearch.security.securityconf.impl.v7.InternalUserV7; import org.opensearch.security.securityconf.impl.v7.RoleMappingsV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.test.framework.cluster.OpenSearchClientProvider.UserCredentialsHolder; import org.opensearch.transport.client.Client; diff --git a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java index 8d63e2d1ac..0750f5c61c 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java +++ b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java @@ -20,17 +20,17 @@ import org.opensearch.rest.RestRequest.Method; import org.opensearch.security.auditlog.AuditLog.Origin; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.test.framework.TestSecurityConfig.User; -import static org.opensearch.security.auditlog.impl.AuditCategory.AUTHENTICATED; -import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; -import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; import static org.opensearch.security.auditlog.impl.AuditMessage.REQUEST_LAYER; import static org.opensearch.security.auditlog.impl.AuditMessage.RESOLVED_INDICES; import static org.opensearch.security.auditlog.impl.AuditMessage.REST_REQUEST_PARAMS; import static org.opensearch.security.auditlog.impl.AuditMessage.REST_REQUEST_PATH; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.AUTHENTICATED; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; public class AuditMessagePredicate implements Predicate { diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java index 43e1129051..d5ce8c4e0d 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java @@ -50,8 +50,8 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.test.framework.AuditConfiguration; import org.opensearch.test.framework.AuthFailureListeners; import org.opensearch.test.framework.AuthzDomain; diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/MinimumSecuritySettingsSupplierFactory.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/MinimumSecuritySettingsSupplierFactory.java index 34a105ea39..a34154bf96 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/MinimumSecuritySettingsSupplierFactory.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/MinimumSecuritySettingsSupplierFactory.java @@ -31,7 +31,7 @@ import java.util.Map; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.test.framework.certificate.TestCertificates; public class MinimumSecuritySettingsSupplierFactory { diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java index f560ef713f..d3c76b9070 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java @@ -69,7 +69,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.Strings; import org.opensearch.core.xcontent.ToXContentObject; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import static java.lang.String.format; import static java.util.Objects.requireNonNull; diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java index c193ae6d7f..24593f4ad4 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java @@ -25,7 +25,7 @@ import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class LegacyRestHandler extends AbstractRestHandler { diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java index 7ab401c7be..cc630c7785 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java @@ -27,7 +27,7 @@ import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class ProtectedRoutesRestHandler extends AbstractRestHandler { diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java index 2100f68a97..86e65818f9 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java @@ -35,9 +35,9 @@ import org.opensearch.core.common.Strings; import org.opensearch.core.rest.RestStatus; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; import com.amazon.dlic.auth.http.jwt.keybyoidc.AuthenticatorUnavailableException; import com.amazon.dlic.auth.http.jwt.keybyoidc.BadCredentialsException; diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java index 45670e5d68..1af16453aa 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java @@ -33,11 +33,11 @@ import org.opensearch.common.logging.DeprecationLogger; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.KeyUtils; import com.nimbusds.jwt.proc.BadJWTException; diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java index 7e7f088069..4d52be47ea 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java @@ -33,7 +33,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import com.amazon.dlic.auth.http.jwt.oidc.json.OpenIdProviderConfiguration; import com.amazon.dlic.util.SettingsBasedSSLConfigurator.SSLConfig; diff --git a/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java index 53d60b7261..c2b0589470 100644 --- a/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java @@ -43,9 +43,9 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.env.Environment; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; import com.amazon.dlic.auth.http.kerberos.util.JaasKrbUtil; import com.amazon.dlic.auth.http.kerberos.util.KrbConstants; diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java b/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java index 6abe934925..c941d21cab 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java @@ -45,7 +45,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.AuthTokenProcessorAction; import org.opensearch.security.filter.SecurityResponse; diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java index c0b9b5b1a9..cde4bfb90e 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java @@ -39,14 +39,14 @@ import org.opensearch.rest.RestRequest; import org.opensearch.security.auth.Destroyable; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.OpenSearchRequest; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestChannelUnsupported; import org.opensearch.security.filter.SecurityResponse; import org.opensearch.security.opensaml.integration.SecurityXMLObjectProviderInitializer; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.PemKeyReader; -import org.opensearch.security.user.AuthCredentials; import com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator; import com.amazon.dlic.auth.http.jwt.keybyoidc.AuthenticatorUnavailableException; diff --git a/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java b/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java index c2f634709e..4b0c4dd2d9 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java @@ -18,9 +18,9 @@ import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.util.Utils; import org.ldaptive.LdapAttribute; diff --git a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java index 3145352013..df55fcdab0 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java @@ -29,9 +29,9 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthenticationBackend; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java index 0ad0da54c6..dff5374c1f 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java @@ -47,11 +47,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.Strings; import org.opensearch.security.auth.AuthorizationBackend; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.util.SSLConfigConstants; import org.opensearch.security.support.PemKeyReader; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java index 70311e5fe3..7f9fff0e5c 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java @@ -29,9 +29,9 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthenticationBackend; import org.opensearch.security.auth.Destroyable; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java index 8c1569bfb6..cca7e368a6 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java @@ -37,9 +37,9 @@ import org.opensearch.core.common.Strings; import org.opensearch.security.auth.AuthorizationBackend; import org.opensearch.security.auth.Destroyable; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/main/java/org/opensearch/security/DefaultObjectMapper.java b/src/main/java/org/opensearch/security/DefaultObjectMapper.java deleted file mode 100644 index 68a537c669..0000000000 --- a/src/main/java/org/opensearch/security/DefaultObjectMapper.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security; - -import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.ImmutableSet; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.InjectableValues; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import com.fasterxml.jackson.databind.exc.MismatchedInputException; -import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - -import org.opensearch.SpecialPermission; - -class ConfigMapSerializer extends StdSerializer> { - private static final Set SENSITIVE_CONFIG_KEYS = Set.of("password"); - - @SuppressWarnings("unchecked") - public ConfigMapSerializer() { - // Pass Map.class to the superclass - super((Class>) (Class) Map.class); - } - - @Override - public void serialize(Map value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeStartObject(); - for (Map.Entry entry : value.entrySet()) { - if (SENSITIVE_CONFIG_KEYS.contains(entry.getKey())) { - gen.writeStringField(entry.getKey(), "******"); // Redact - } else { - gen.writeObjectField(entry.getKey(), entry.getValue()); - } - } - gen.writeEndObject(); - } -} - -public class DefaultObjectMapper { - public static final ObjectMapper objectMapper = new ObjectMapper(); - public final static ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory()); - private static final ObjectMapper defaulOmittingObjectMapper = new ObjectMapper(); - - static { - objectMapper.setSerializationInclusion(Include.NON_NULL); - // exclude sensitive information from the request body, - // if jackson cant parse the entity, e.g. passwords, hashes and so on, - // but provides which property is unknown - objectMapper.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); - defaulOmittingObjectMapper.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); - YAML_MAPPER.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); - // objectMapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS); - objectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); - defaulOmittingObjectMapper.setSerializationInclusion(Include.NON_DEFAULT); - defaulOmittingObjectMapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); - YAML_MAPPER.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); - } - - private DefaultObjectMapper() {} - - public static void inject(final InjectableValues.Std injectableValues) { - objectMapper.setInjectableValues(injectableValues); - YAML_MAPPER.setInjectableValues(injectableValues); - defaulOmittingObjectMapper.setInjectableValues(injectableValues); - } - - public static boolean getOrDefault(Map properties, String key, boolean defaultValue) throws JsonProcessingException { - Object value = properties.get(key); - if (value == null) { - return defaultValue; - } else if (value instanceof Boolean) { - return (boolean) value; - } else if (value instanceof String) { - String text = ((String) value).trim(); - if ("true".equals(text) || "True".equals(text)) { - return true; - } - if ("false".equals(text) || "False".equals(text)) { - return false; - } - throw InvalidFormatException.from( - null, - "Cannot deserialize value of type 'boolean' from String \"" + text + "\": only \"true\" or \"false\" recognized)", - null, - Boolean.class - ); - } - throw MismatchedInputException.from( - null, - Boolean.class, - "Cannot deserialize instance of 'boolean' out of '" + value + "' (Property: " + key + ")" - ); - } - - @SuppressWarnings("unchecked") - public static T getOrDefault(Map properties, String key, T defaultValue) { - T value = (T) properties.get(key); - return value != null ? value : defaultValue; - } - - @SuppressWarnings("removal") - public static T readTree(JsonNode node, Class clazz) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.treeToValue(node, clazz)); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - } - - @SuppressWarnings("removal") - public static T readValue(String string, Class clazz) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readValue(string, clazz)); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - } - - @SuppressWarnings("removal") - public static JsonNode readTree(String string) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readTree(string)); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - } - - @SuppressWarnings("removal") - public static String writeValueAsString(Object value, boolean omitDefaults) throws JsonProcessingException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged( - (PrivilegedExceptionAction) () -> (omitDefaults ? defaulOmittingObjectMapper : objectMapper).writeValueAsString( - value - ) - ); - } catch (final PrivilegedActionException e) { - throw (JsonProcessingException) e.getCause(); - } - - } - - @SuppressWarnings("removal") - public static String writeValueAsStringAndRedactSensitive(Object value) throws JsonProcessingException { - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - SimpleModule module = new SimpleModule(); - module.addSerializer(new ConfigMapSerializer()); - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(module); - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> mapper.writeValueAsString(value)); - } catch (final PrivilegedActionException e) { - throw (JsonProcessingException) e.getCause(); - } - - } - - @SuppressWarnings("removal") - public static T readValue(String string, TypeReference tr) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public T run() throws Exception { - return objectMapper.readValue(string, tr); - } - }); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - - } - - @SuppressWarnings("removal") - public static T readValue(String string, JavaType jt) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.readValue(string, jt)); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - } - - @SuppressWarnings("removal") - public static T convertValue(JsonNode jsonNode, JavaType jt) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> objectMapper.convertValue(jsonNode, jt)); - } catch (final PrivilegedActionException e) { - throw (IOException) e.getCause(); - } - } - - public static TypeFactory getTypeFactory() { - return objectMapper.getTypeFactory(); - } - - public static Set getFields(Class cls) { - return objectMapper.getSerializationConfig() - .introspect(getTypeFactory().constructType(cls)) - .findProperties() - .stream() - .map(BeanPropertyDefinition::getName) - .collect(ImmutableSet.toImmutableSet()); - } -} diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 56fda88a42..a1145aa0c7 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -144,6 +144,7 @@ import org.opensearch.security.auditlog.config.AuditConfig.Filter.FilterEntries; import org.opensearch.security.auditlog.impl.AuditLogImpl; import org.opensearch.security.auth.BackendRegistry; +import org.opensearch.security.common.configuration.AdminDNs; import org.opensearch.security.common.resources.ResourceAccessHandler; import org.opensearch.security.common.resources.ResourceIndexListener; import org.opensearch.security.common.resources.ResourcePluginInfo; @@ -154,9 +155,10 @@ import org.opensearch.security.common.resources.rest.ResourceAccessAction; import org.opensearch.security.common.resources.rest.ResourceAccessRestAction; import org.opensearch.security.common.resources.rest.ResourceAccessTransportAction; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.compliance.ComplianceIndexingOperationListener; import org.opensearch.security.compliance.ComplianceIndexingOperationListenerImpl; -import org.opensearch.security.configuration.AdminDNs; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.configuration.CompatConfig; import org.opensearch.security.configuration.ConfigurationRepository; @@ -205,7 +207,6 @@ import org.opensearch.security.ssl.transport.DefaultPrincipalExtractor; import org.opensearch.security.ssl.util.SSLConfigConstants; import org.opensearch.security.state.SecurityMetadata; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.GuardedSearchOperationWrapper; import org.opensearch.security.support.HeaderHelper; import org.opensearch.security.support.ModuleInfo; @@ -214,7 +215,6 @@ import org.opensearch.security.transport.DefaultInterClusterRequestEvaluator; import org.opensearch.security.transport.InterClusterRequestEvaluator; import org.opensearch.security.transport.SecurityInterceptor; -import org.opensearch.security.user.User; import org.opensearch.security.user.UserService; import org.opensearch.tasks.Task; import org.opensearch.telemetry.tracing.Tracer; @@ -233,16 +233,16 @@ import org.opensearch.transport.netty4.ssl.SecureNetty4Transport; import org.opensearch.watcher.ResourceWatcherService; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.SECURITY_CONFIG_UPDATE; import static org.opensearch.security.privileges.dlsfls.FieldMasking.Config.BLAKE2B_LEGACY_DEFAULT; import static org.opensearch.security.setting.DeprecatedSettings.checkForDeprecatedSetting; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; // CS-ENFORCE-SINGLE diff --git a/src/main/java/org/opensearch/security/action/onbehalf/CreateOnBehalfOfTokenAction.java b/src/main/java/org/opensearch/security/action/onbehalf/CreateOnBehalfOfTokenAction.java index ec929bf078..7dc6114b5b 100644 --- a/src/main/java/org/opensearch/security/action/onbehalf/CreateOnBehalfOfTokenAction.java +++ b/src/main/java/org/opensearch/security/action/onbehalf/CreateOnBehalfOfTokenAction.java @@ -32,8 +32,8 @@ import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_API_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_API_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class CreateOnBehalfOfTokenAction extends BaseRestHandler { diff --git a/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java b/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java index 4bc6238765..b4fc7d6213 100644 --- a/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java +++ b/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java @@ -32,10 +32,10 @@ import org.opensearch.common.inject.Inject; import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; -import org.opensearch.security.configuration.AdminDNs; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.support.HeaderHelper; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportService; diff --git a/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java b/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java index 3beb956209..c7bbd411a7 100644 --- a/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java +++ b/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java @@ -30,15 +30,15 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.dlic.rest.support.Utils; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; -import static org.opensearch.security.DefaultObjectMapper.getOrDefault; -import static org.opensearch.security.support.ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT; +import static org.opensearch.security.common.support.DefaultObjectMapper.getOrDefault; /** * Class represents configuration for audit logging. diff --git a/src/main/java/org/opensearch/security/auditlog/config/ThreadPoolConfig.java b/src/main/java/org/opensearch/security/auditlog/config/ThreadPoolConfig.java index a8c44e0cee..449417ec3f 100644 --- a/src/main/java/org/opensearch/security/auditlog/config/ThreadPoolConfig.java +++ b/src/main/java/org/opensearch/security/auditlog/config/ThreadPoolConfig.java @@ -12,7 +12,7 @@ package org.opensearch.security.auditlog.config; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; public class ThreadPoolConfig { private static final int DEFAULT_THREAD_POOL_SIZE = 10; diff --git a/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java b/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java index 302ac96442..9bafe43f8b 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java @@ -63,17 +63,18 @@ import org.opensearch.index.engine.Engine.Index; import org.opensearch.index.engine.Engine.IndexResult; import org.opensearch.index.get.GetResult; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.config.AuditConfig; import org.opensearch.security.auth.AuthDomain; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.User; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.dlic.rest.support.Utils; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.securityconf.DynamicConfigModel; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportRequest; diff --git a/src/main/java/org/opensearch/security/auditlog/impl/AuditCategory.java b/src/main/java/org/opensearch/security/auditlog/impl/AuditCategory.java deleted file mode 100644 index caf6938b14..0000000000 --- a/src/main/java/org/opensearch/security/auditlog/impl/AuditCategory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.auditlog.impl; - -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -import com.google.common.collect.ImmutableSet; - -public enum AuditCategory { - BAD_HEADERS, - FAILED_LOGIN, - MISSING_PRIVILEGES, - GRANTED_PRIVILEGES, - OPENDISTRO_SECURITY_INDEX_ATTEMPT, - SSL_EXCEPTION, - AUTHENTICATED, - INDEX_EVENT, - COMPLIANCE_DOC_READ, - COMPLIANCE_DOC_WRITE, - COMPLIANCE_EXTERNAL_CONFIG, - COMPLIANCE_INTERNAL_CONFIG_READ, - COMPLIANCE_INTERNAL_CONFIG_WRITE; - - public static Set parse(final Collection categories) { - if (categories.isEmpty()) return Collections.emptySet(); - - return categories.stream().map(String::toUpperCase).map(AuditCategory::valueOf).collect(ImmutableSet.toImmutableSet()); - } -} diff --git a/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java b/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java index 81695b702b..1ea1ad39cc 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java @@ -45,11 +45,12 @@ import org.opensearch.security.auditlog.AuditLog.Operation; import org.opensearch.security.auditlog.AuditLog.Origin; import org.opensearch.security.auditlog.config.AuditConfig; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.filter.OpenSearchRequest; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.WildcardMatcher; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; diff --git a/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java b/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java index ea4289150e..f2fee421ed 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java @@ -54,8 +54,9 @@ import org.opensearch.index.reindex.ReindexRequest; import org.opensearch.index.reindex.UpdateByQueryRequest; import org.opensearch.security.auditlog.AuditLog.Origin; -import org.opensearch.security.dlic.rest.support.Utils; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportRequest; diff --git a/src/main/java/org/opensearch/security/auditlog/routing/AuditMessageRouter.java b/src/main/java/org/opensearch/security/auditlog/routing/AuditMessageRouter.java index 83fe26151e..4edf2e1e5a 100644 --- a/src/main/java/org/opensearch/security/auditlog/routing/AuditMessageRouter.java +++ b/src/main/java/org/opensearch/security/auditlog/routing/AuditMessageRouter.java @@ -25,12 +25,12 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.config.ThreadPoolConfig; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.sink.AuditLogSink; import org.opensearch.security.auditlog.sink.SinkProvider; -import org.opensearch.security.dlic.rest.support.Utils; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/AbstractInternalOpenSearchSink.java b/src/main/java/org/opensearch/security/auditlog/sink/AbstractInternalOpenSearchSink.java index 05d8e409cf..532f962d44 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/AbstractInternalOpenSearchSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/AbstractInternalOpenSearchSink.java @@ -24,7 +24,7 @@ import org.opensearch.common.unit.TimeValue; import org.opensearch.common.util.concurrent.ThreadContext.StoredContext; import org.opensearch.security.auditlog.impl.AuditMessage; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/AuditLogSink.java b/src/main/java/org/opensearch/security/auditlog/sink/AuditLogSink.java index d034014612..d411f67e4b 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/AuditLogSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/AuditLogSink.java @@ -21,7 +21,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.impl.AuditMessage; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/ExternalOpenSearchSink.java b/src/main/java/org/opensearch/security/auditlog/sink/ExternalOpenSearchSink.java index 7bde676399..dcab13944a 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/ExternalOpenSearchSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/ExternalOpenSearchSink.java @@ -22,10 +22,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.httpclient.HttpClient; import org.opensearch.security.httpclient.HttpClient.HttpClientBuilder; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.PemKeyReader; import org.joda.time.format.DateTimeFormat; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchDataStreamSink.java b/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchDataStreamSink.java index 1c4eb8f4de..b2c1f61ec2 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchDataStreamSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchDataStreamSink.java @@ -27,7 +27,7 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.impl.AuditMessage; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.RemoteTransportException; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchSink.java b/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchSink.java index 79c6514138..5383158b19 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/InternalOpenSearchSink.java @@ -19,7 +19,7 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.impl.AuditMessage; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/SinkProvider.java b/src/main/java/org/opensearch/security/auditlog/sink/SinkProvider.java index 9e2758b31e..28360dd3fa 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/SinkProvider.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/SinkProvider.java @@ -21,8 +21,8 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; -import org.opensearch.security.dlic.rest.support.Utils; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/auditlog/sink/WebhookSink.java b/src/main/java/org/opensearch/security/auditlog/sink/WebhookSink.java index 40c278026b..7c2fbd4066 100644 --- a/src/main/java/org/opensearch/security/auditlog/sink/WebhookSink.java +++ b/src/main/java/org/opensearch/security/auditlog/sink/WebhookSink.java @@ -46,8 +46,8 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.Strings; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.PemKeyReader; import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD; diff --git a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java index 9f23391275..2e26574a1b 100644 --- a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java +++ b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java @@ -19,8 +19,8 @@ import java.net.InetAddress; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.support.HostAndCidrMatcher; -import org.opensearch.security.user.AuthCredentials; public interface AuthFailureListener { void onAuthFailure(InetAddress remoteAddress, AuthCredentials authCredentials, Object request); diff --git a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java index 0296f56a4a..d4a14f657c 100644 --- a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java @@ -27,8 +27,8 @@ package org.opensearch.security.auth; import org.opensearch.OpenSearchSecurityException; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; /** * OpenSearch Security custom authentication backends need to implement this interface. diff --git a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java index 3aea412e69..8f12a67c99 100644 --- a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java @@ -27,8 +27,8 @@ package org.opensearch.security.auth; import org.opensearch.OpenSearchSecurityException; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; /** * OpenSearch Security custom authorization backends need to implement this interface. diff --git a/src/main/java/org/opensearch/security/auth/BackendRegistry.java b/src/main/java/org/opensearch/security/auth/BackendRegistry.java index a8295a410f..ce4610394b 100644 --- a/src/main/java/org/opensearch/security/auth/BackendRegistry.java +++ b/src/main/java/org/opensearch/security/auth/BackendRegistry.java @@ -59,16 +59,16 @@ import org.opensearch.security.auth.blocking.ClientBlockRegistry; import org.opensearch.security.auth.internal.NoOpAuthenticationBackend; import org.opensearch.security.common.auth.UserSubjectImpl; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestChannel; import org.opensearch.security.filter.SecurityResponse; import org.opensearch.security.http.XFFResolver; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HostAndCidrMatcher; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.greenrobot.eventbus.Subscribe; diff --git a/src/main/java/org/opensearch/security/auth/HTTPAuthenticator.java b/src/main/java/org/opensearch/security/auth/HTTPAuthenticator.java index 927dc0e286..8a476e720f 100644 --- a/src/main/java/org/opensearch/security/auth/HTTPAuthenticator.java +++ b/src/main/java/org/opensearch/security/auth/HTTPAuthenticator.java @@ -33,9 +33,9 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.rest.RestRequest; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; /** * OpenSearch Security custom HTTP authenticators need to implement this interface. diff --git a/src/main/java/org/opensearch/security/auth/RolesInjector.java b/src/main/java/org/opensearch/security/auth/RolesInjector.java index 6c0eaa0732..ff8047730c 100644 --- a/src/main/java/org/opensearch/security/auth/RolesInjector.java +++ b/src/main/java/org/opensearch/security/auth/RolesInjector.java @@ -24,8 +24,8 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportRequest; diff --git a/src/main/java/org/opensearch/security/auth/UserInjector.java b/src/main/java/org/opensearch/security/auth/UserInjector.java index 65a7055238..c9e68ba7f8 100644 --- a/src/main/java/org/opensearch/security/auth/UserInjector.java +++ b/src/main/java/org/opensearch/security/auth/UserInjector.java @@ -43,10 +43,10 @@ import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.common.transport.TransportAddress; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.filter.SecurityRequestChannel; import org.opensearch.security.http.XFFResolver; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; public class UserInjector { diff --git a/src/main/java/org/opensearch/security/auth/internal/InternalAuthenticationBackend.java b/src/main/java/org/opensearch/security/auth/internal/InternalAuthenticationBackend.java index be09638d9d..a1b09e9365 100644 --- a/src/main/java/org/opensearch/security/auth/internal/InternalAuthenticationBackend.java +++ b/src/main/java/org/opensearch/security/auth/internal/InternalAuthenticationBackend.java @@ -38,10 +38,10 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.security.auth.AuthenticationBackend; import org.opensearch.security.auth.AuthorizationBackend; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.securityconf.InternalUsersModel; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import org.greenrobot.eventbus.Subscribe; diff --git a/src/main/java/org/opensearch/security/auth/internal/NoOpAuthenticationBackend.java b/src/main/java/org/opensearch/security/auth/internal/NoOpAuthenticationBackend.java index 299a1a4577..25495b3d90 100644 --- a/src/main/java/org/opensearch/security/auth/internal/NoOpAuthenticationBackend.java +++ b/src/main/java/org/opensearch/security/auth/internal/NoOpAuthenticationBackend.java @@ -30,8 +30,8 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthenticationBackend; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; public class NoOpAuthenticationBackend implements AuthenticationBackend { diff --git a/src/main/java/org/opensearch/security/auth/internal/NoOpAuthorizationBackend.java b/src/main/java/org/opensearch/security/auth/internal/NoOpAuthorizationBackend.java index 581cfc8da6..bb9fb4caff 100644 --- a/src/main/java/org/opensearch/security/auth/internal/NoOpAuthorizationBackend.java +++ b/src/main/java/org/opensearch/security/auth/internal/NoOpAuthorizationBackend.java @@ -30,8 +30,8 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthorizationBackend; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; public class NoOpAuthorizationBackend implements AuthorizationBackend { diff --git a/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java index a266109c66..61d99d5a1a 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java @@ -26,8 +26,8 @@ import org.opensearch.security.auth.AuthFailureListener; import org.opensearch.security.auth.blocking.ClientBlockRegistry; import org.opensearch.security.auth.blocking.HeapBasedClientBlockRegistry; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.support.HostAndCidrMatcher; -import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.ratetracking.RateTracker; public abstract class AbstractRateLimiter implements AuthFailureListener, ClientBlockRegistry { diff --git a/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java index 876615870a..62cc8a92d8 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java @@ -23,7 +23,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthFailureListener; import org.opensearch.security.auth.blocking.ClientBlockRegistry; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; public class AddressBasedRateLimiter extends AbstractRateLimiter implements diff --git a/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java index 3fd0c12246..0f7e783956 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java @@ -23,7 +23,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthFailureListener; import org.opensearch.security.auth.blocking.ClientBlockRegistry; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; public class UserNameBasedRateLimiter extends AbstractRateLimiter implements AuthFailureListener, ClientBlockRegistry { diff --git a/src/main/java/org/opensearch/security/compliance/ComplianceConfig.java b/src/main/java/org/opensearch/security/compliance/ComplianceConfig.java index b149f2604a..fed4afdc04 100644 --- a/src/main/java/org/opensearch/security/compliance/ComplianceConfig.java +++ b/src/main/java/org/opensearch/security/compliance/ComplianceConfig.java @@ -54,17 +54,17 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.Strings; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.support.WildcardMatcher; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import static org.opensearch.security.DefaultObjectMapper.getOrDefault; +import static org.opensearch.security.common.support.DefaultObjectMapper.getOrDefault; /** * This class represents all configurations for compliance. diff --git a/src/main/java/org/opensearch/security/compliance/FieldReadCallback.java b/src/main/java/org/opensearch/security/compliance/FieldReadCallback.java index c002535b3d..c8d4c9c09a 100644 --- a/src/main/java/org/opensearch/security/compliance/FieldReadCallback.java +++ b/src/main/java/org/opensearch/security/compliance/FieldReadCallback.java @@ -31,7 +31,7 @@ import org.opensearch.index.IndexService; import org.opensearch.index.mapper.Uid; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.dlic.rest.support.Utils; import org.opensearch.security.privileges.dlsfls.FieldMasking; import org.opensearch.security.support.HeaderHelper; import org.opensearch.security.support.JsonFlattener; diff --git a/src/main/java/org/opensearch/security/configuration/AdminDNs.java b/src/main/java/org/opensearch/security/configuration/AdminDNs.java deleted file mode 100644 index cdbbf8545b..0000000000 --- a/src/main/java/org/opensearch/security/configuration/AdminDNs.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.configuration; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import com.google.common.collect.ImmutableMap; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; - -public class AdminDNs { - - protected final Logger log = LogManager.getLogger(AdminDNs.class); - private final Set adminDn = new HashSet(); - private final Set adminUsernames = new HashSet(); - private final Map allowedDnsImpersonations; - private final Map allowedRestImpersonations; - private boolean injectUserEnabled; - private boolean injectAdminUserEnabled; - - public AdminDNs(final Settings settings) { - - this.injectUserEnabled = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false); - this.injectAdminUserEnabled = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, false); - - final List adminDnsA = settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Collections.emptyList()); - - for (String dn : adminDnsA) { - try { - log.debug("{} is registered as an admin dn", dn); - adminDn.add(new LdapName(dn)); - } catch (final InvalidNameException e) { - // make sure to log correctly depending on user injection settings - if (injectUserEnabled && injectAdminUserEnabled) { - if (log.isDebugEnabled()) { - log.debug("Admin DN not an LDAP name, but admin user injection enabled. Will add {} to admin usernames", dn); - } - adminUsernames.add(dn); - } else { - log.error("Unable to parse admin dn {}", dn, e); - } - } - } - - log.debug("Loaded {} admin DN's {}", adminDn.size(), adminDn); - - final Settings impersonationDns = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_IMPERSONATION_DN + "."); - - allowedDnsImpersonations = impersonationDns.keySet() - .stream() - .map(this::toLdapName) - .filter(Objects::nonNull) - .collect( - ImmutableMap.toImmutableMap( - Function.identity(), - ldapName -> WildcardMatcher.from(settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_IMPERSONATION_DN + "." + ldapName)) - ) - ); - - log.debug("Loaded {} impersonation DN's {}", allowedDnsImpersonations.size(), allowedDnsImpersonations); - - final Settings impersonationUsersRest = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + "."); - - allowedRestImpersonations = impersonationUsersRest.keySet() - .stream() - .collect( - ImmutableMap.toImmutableMap( - Function.identity(), - user -> WildcardMatcher.from(settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + "." + user)) - ) - ); - - log.debug("Loaded {} impersonation users for REST {}", allowedRestImpersonations.size(), allowedRestImpersonations); - } - - private LdapName toLdapName(String dn) { - try { - return new LdapName(dn); - } catch (final InvalidNameException e) { - log.error("Unable to parse allowedImpersonations dn {}", dn, e); - } - return null; - } - - public boolean isAdmin(User user) { - if (isAdminDN(user.getName())) { - return true; - } - - // ThreadContext injected user, may be admin user, only if both flags are enabled and user is injected - if (injectUserEnabled && injectAdminUserEnabled && user.isInjected() && adminUsernames.contains(user.getName())) { - return true; - } - return false; - } - - public boolean isAdminDN(String dn) { - - if (dn == null) return false; - - try { - return isAdminDN(new LdapName(dn)); - } catch (InvalidNameException e) { - return false; - } - } - - private boolean isAdminDN(LdapName dn) { - if (dn == null) return false; - - boolean isAdmin = adminDn.contains(dn); - - if (log.isTraceEnabled()) { - log.trace("Is principal {} an admin cert? {}", dn.toString(), isAdmin); - } - - return isAdmin; - } - - public boolean isRestImpersonationAllowed(final String originalUser, final String impersonated) { - return (originalUser != null) - ? allowedRestImpersonations.getOrDefault(originalUser, WildcardMatcher.NONE).test(impersonated) - : false; - } -} diff --git a/src/main/java/org/opensearch/security/configuration/CompatConfig.java b/src/main/java/org/opensearch/security/configuration/CompatConfig.java index a8de00f64e..5b61e2ccc4 100644 --- a/src/main/java/org/opensearch/security/configuration/CompatConfig.java +++ b/src/main/java/org/opensearch/security/configuration/CompatConfig.java @@ -31,13 +31,13 @@ import org.opensearch.common.settings.Settings; import org.opensearch.env.Environment; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.DynamicConfigModel; import org.opensearch.security.setting.OpensearchDynamicSetting; -import org.opensearch.security.support.ConfigConstants; import org.greenrobot.eventbus.Subscribe; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY; public class CompatConfig { diff --git a/src/main/java/org/opensearch/security/configuration/ConfigurationLoaderSecurity7.java b/src/main/java/org/opensearch/security/configuration/ConfigurationLoaderSecurity7.java index 6a61828874..638d0fbd1b 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigurationLoaderSecurity7.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigurationLoaderSecurity7.java @@ -51,11 +51,11 @@ import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.ConfigHelper; import org.opensearch.security.support.SecurityUtils; import org.opensearch.threadpool.ThreadPool; diff --git a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java index 1c3c5562b4..41efe469d8 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java @@ -80,19 +80,19 @@ import org.opensearch.env.Environment; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.config.AuditConfig; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.DynamicConfigFactory; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.state.SecurityMetadata; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.ConfigHelper; import org.opensearch.security.support.SecurityIndexHandler; import org.opensearch.security.support.SecurityUtils; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE; public class ConfigurationRepository implements ClusterStateListener { private static final Logger LOGGER = LogManager.getLogger(ConfigurationRepository.class); diff --git a/src/main/java/org/opensearch/security/configuration/DlsFilterLevelActionHandler.java b/src/main/java/org/opensearch/security/configuration/DlsFilterLevelActionHandler.java index 11d42c9758..d8774ad182 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFilterLevelActionHandler.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFilterLevelActionHandler.java @@ -57,6 +57,7 @@ import org.opensearch.script.mustache.SearchTemplateAction; import org.opensearch.search.SearchHit; import org.opensearch.search.builder.SearchSourceBuilder; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.privileges.DocumentAllowList; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.dlsfls.DlsRestriction; @@ -64,7 +65,6 @@ import org.opensearch.security.privileges.dlsfls.IndexToRuleMap; import org.opensearch.security.queries.QueryBuilderTraverser; import org.opensearch.security.resolver.IndexResolverReplacer.Resolved; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.ReflectiveAttributeAccessors; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java b/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java index 92156dc0cc..c7cce572b6 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsFilterLeafReader.java @@ -65,12 +65,12 @@ import org.opensearch.core.index.shard.ShardId; import org.opensearch.index.IndexService; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.compliance.ComplianceConfig; import org.opensearch.security.compliance.FieldReadCallback; import org.opensearch.security.privileges.dlsfls.FieldMasking; import org.opensearch.security.privileges.dlsfls.FieldPrivileges; import org.opensearch.security.privileges.dlsfls.FlsStoredFieldVisitor; -import org.opensearch.security.support.ConfigConstants; class DlsFlsFilterLeafReader extends SequentialStoredFieldsLeafReader { diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java index 74c5b4d3be..3dd05a73a6 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java @@ -66,6 +66,7 @@ import org.opensearch.search.internal.SearchContext; import org.opensearch.search.query.QuerySearchResult; import org.opensearch.security.OpenSearchSecurityPlugin; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.privileges.DocumentAllowList; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluationException; @@ -79,7 +80,6 @@ import org.opensearch.security.securityconf.DynamicConfigFactory; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/configuration/PrivilegesInterceptorImpl.java b/src/main/java/org/opensearch/security/configuration/PrivilegesInterceptorImpl.java index 8d71041106..5ec837714e 100644 --- a/src/main/java/org/opensearch/security/configuration/PrivilegesInterceptorImpl.java +++ b/src/main/java/org/opensearch/security/configuration/PrivilegesInterceptorImpl.java @@ -45,11 +45,11 @@ import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.service.ClusterService; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.DocumentAllowList; import org.opensearch.security.privileges.PrivilegesInterceptor; import org.opensearch.security.resolver.IndexResolverReplacer.Resolved; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/configuration/Salt.java b/src/main/java/org/opensearch/security/configuration/Salt.java index e13a430c79..e01e77ae71 100644 --- a/src/main/java/org/opensearch/security/configuration/Salt.java +++ b/src/main/java/org/opensearch/security/configuration/Salt.java @@ -21,7 +21,7 @@ import org.opensearch.OpenSearchException; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; /** * Configuration class to store salt used for FLS anonymization diff --git a/src/main/java/org/opensearch/security/configuration/SecurityFlsDlsIndexSearcherWrapper.java b/src/main/java/org/opensearch/security/configuration/SecurityFlsDlsIndexSearcherWrapper.java index 4f7a412097..c4f5dcd5bb 100644 --- a/src/main/java/org/opensearch/security/configuration/SecurityFlsDlsIndexSearcherWrapper.java +++ b/src/main/java/org/opensearch/security/configuration/SecurityFlsDlsIndexSearcherWrapper.java @@ -35,6 +35,8 @@ import org.opensearch.index.query.QueryShardContext; import org.opensearch.index.shard.ShardUtils; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.compliance.ComplianceIndexingOperationListener; import org.opensearch.security.privileges.DocumentAllowList; import org.opensearch.security.privileges.PrivilegesEvaluationContext; @@ -45,7 +47,6 @@ import org.opensearch.security.privileges.dlsfls.DlsRestriction; import org.opensearch.security.privileges.dlsfls.FieldMasking; import org.opensearch.security.privileges.dlsfls.FieldPrivileges; -import org.opensearch.security.support.ConfigConstants; public class SecurityFlsDlsIndexSearcherWrapper extends SystemIndexSearcherWrapper { diff --git a/src/main/java/org/opensearch/security/configuration/SystemIndexSearcherWrapper.java b/src/main/java/org/opensearch/security/configuration/SystemIndexSearcherWrapper.java index 080e2a8a08..22b481fba3 100644 --- a/src/main/java/org/opensearch/security/configuration/SystemIndexSearcherWrapper.java +++ b/src/main/java/org/opensearch/security/configuration/SystemIndexSearcherWrapper.java @@ -40,15 +40,16 @@ import org.opensearch.core.index.Index; import org.opensearch.index.IndexService; import org.opensearch.indices.SystemIndexRegistry; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.privileges.PrivilegesEvaluatorResponse; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.ConfigModel; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.greenrobot.eventbus.Subscribe; diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/AbstractApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/AbstractApiAction.java index d235e53680..0f0a543b3a 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/AbstractApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/AbstractApiAction.java @@ -52,7 +52,9 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.ValidationResult; @@ -60,8 +62,6 @@ import org.opensearch.security.securityconf.DynamicConfigFactory; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; import org.opensearch.transport.client.node.NodeClient; @@ -70,14 +70,14 @@ import com.flipkart.zjsonpatch.JsonPatch; import com.flipkart.zjsonpatch.JsonPatchApplicationException; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.conflict; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbidden; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbiddenMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.internalServerError; +import static org.opensearch.security.common.dlic.rest.api.Responses.payload; +import static org.opensearch.security.common.dlic.rest.support.Utils.withIOException; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.conflict; -import static org.opensearch.security.dlic.rest.api.Responses.forbidden; -import static org.opensearch.security.dlic.rest.api.Responses.forbiddenMessage; -import static org.opensearch.security.dlic.rest.api.Responses.internalServerError; -import static org.opensearch.security.dlic.rest.api.Responses.payload; -import static org.opensearch.security.dlic.rest.support.Utils.withIOException; public abstract class AbstractApiAction extends BaseRestHandler { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/AccountApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/AccountApiAction.java index 45f97b0931..d262858cae 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/AccountApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/AccountApiAction.java @@ -27,6 +27,8 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -35,17 +37,15 @@ import org.opensearch.security.securityconf.Hashed; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SecurityJsonNode; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.response; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; /** * Rest API action to fetch or update account details of the signed-in user. diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiAction.java index 751de30905..87516e1128 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiAction.java @@ -28,7 +28,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest.Method; import org.opensearch.security.OpenSearchSecurityPlugin; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.dlic.rest.support.Utils; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -38,11 +38,11 @@ import org.opensearch.security.securityconf.impl.v7.ActionGroupsV7; import org.opensearch.threadpool.ThreadPool; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; public class ActionGroupsApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/AllowlistApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/AllowlistApiAction.java index 8462ec3fcf..fb5081b513 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/AllowlistApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/AllowlistApiAction.java @@ -21,11 +21,11 @@ import org.opensearch.common.inject.Inject; import org.opensearch.common.settings.Settings; import org.opensearch.rest.RestRequest; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.tools.SecurityAdmin; import org.opensearch.threadpool.ThreadPool; diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/AuditApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/AuditApiAction.java index 690458da2f..7632118fdf 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/AuditApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/AuditApiAction.java @@ -26,11 +26,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.configuration.StaticResourceException; -import org.opensearch.security.dlic.rest.support.Utils; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -38,12 +38,12 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; +import static org.opensearch.security.common.dlic.rest.api.Responses.conflictMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.methodNotImplementedMessage; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; -import static org.opensearch.security.dlic.rest.api.Responses.conflictMessage; -import static org.opensearch.security.dlic.rest.api.Responses.methodNotImplementedMessage; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; /** * Rest handler for fetching and updating audit configuration. diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/AuthTokenProcessorAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/AuthTokenProcessorAction.java index 60fdacfd6d..17cfb71819 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/AuthTokenProcessorAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/AuthTokenProcessorAction.java @@ -22,10 +22,10 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class AuthTokenProcessorAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/CertificatesApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/CertificatesApiAction.java index 61f1695b21..5e0078bf24 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/CertificatesApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/CertificatesApiAction.java @@ -28,11 +28,11 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.internalServerError; -import static org.opensearch.security.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.internalServerError; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_API_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_API_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; public class CertificatesApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiAction.java index f613da815e..008b6da7e9 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiAction.java @@ -45,8 +45,8 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.dlic.rest.support.Utils; import org.opensearch.security.configuration.ConfigurationRepository; -import org.opensearch.security.dlic.rest.support.Utils; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -60,12 +60,12 @@ import com.flipkart.zjsonpatch.DiffFlags; import com.flipkart.zjsonpatch.JsonDiff; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.response; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.withIOException; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.withIOException; public class ConfigUpgradeApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/FlushCacheApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/FlushCacheApiAction.java index aa7ee50940..cb47749734 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/FlushCacheApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/FlushCacheApiAction.java @@ -28,11 +28,11 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.internalServerError; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.internalServerError; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class FlushCacheApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/InternalUsersApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/InternalUsersApiAction.java index f0eeb89926..e1b38281c0 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/InternalUsersApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/InternalUsersApiAction.java @@ -41,15 +41,15 @@ import org.opensearch.security.user.UserServiceException; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.badRequest; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.methodNotImplementedMessage; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.payload; -import static org.opensearch.security.dlic.rest.api.Responses.response; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequest; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.methodNotImplementedMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.payload; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class InternalUsersApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiAction.java index 4782f4686a..29133d79f5 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiAction.java @@ -30,6 +30,7 @@ import org.opensearch.core.xcontent.ToXContent; import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -38,17 +39,16 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.ConfigV7; import org.opensearch.security.securityconf.impl.v7.ConfigV7.Authc; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.PUT; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.response; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class MultiTenancyConfigApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/NodesDnApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/NodesDnApiAction.java index d7d13014c6..f2f93df1c3 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/NodesDnApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/NodesDnApiAction.java @@ -27,6 +27,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -34,14 +35,13 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.NodesDn; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.tools.SecurityAdmin; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.forbiddenMessage; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbiddenMessage; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; /** * This class implements CRUD operations to manage dynamic NodesDn. The primary usecase is targeted at cross-cluster where diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/PermissionsInfoAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/PermissionsInfoAction.java index db67e9b979..b95982224f 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/PermissionsInfoAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/PermissionsInfoAction.java @@ -33,19 +33,19 @@ import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.ssl.transport.PrincipalExtractor; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; import org.opensearch.transport.client.node.NodeClient; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; /** * Provides the evaluated REST API permissions for the currently logged in user diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RateLimitersApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/RateLimitersApiAction.java index b250923471..e1bda3031d 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RateLimitersApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RateLimitersApiAction.java @@ -26,7 +26,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; @@ -39,14 +39,14 @@ import static org.opensearch.rest.RestRequest.Method.DELETE; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.PUT; -import static org.opensearch.security.dlic.rest.api.Responses.badRequest; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.notFound; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.response; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequest; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.notFound; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.securityconf.impl.v7.ConfigV7.ALLOWED_TRIES_DEFAULT; import static org.opensearch.security.securityconf.impl.v7.ConfigV7.BLOCK_EXPIRY_SECONDS_DEFAULT; import static org.opensearch.security.securityconf.impl.v7.ConfigV7.MAX_BLOCKED_CLIENTS_DEFAULT; diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RequestHandler.java b/src/main/java/org/opensearch/security/dlic/rest/api/RequestHandler.java index b88abd6879..893fc2cb40 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RequestHandler.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RequestHandler.java @@ -28,11 +28,11 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.transport.client.Client; -import static org.opensearch.security.dlic.rest.api.Responses.created; -import static org.opensearch.security.dlic.rest.api.Responses.forbidden; -import static org.opensearch.security.dlic.rest.api.Responses.methodNotImplemented; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.api.Responses.created; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbidden; +import static org.opensearch.security.common.dlic.rest.api.Responses.methodNotImplemented; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; @FunctionalInterface public interface RequestHandler { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/Responses.java b/src/main/java/org/opensearch/security/dlic/rest/api/Responses.java deleted file mode 100644 index f0d90af6a0..0000000000 --- a/src/main/java/org/opensearch/security/dlic/rest/api/Responses.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.dlic.rest.api; - -import java.io.IOException; - -import org.opensearch.ExceptionsHelper; -import org.opensearch.core.rest.RestStatus; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; - -public class Responses { - - public static void ok(final RestChannel channel, final String message) { - response(channel, RestStatus.OK, message); - } - - public static void ok(final RestChannel channel, final ToXContent toXContent) { - response(channel, RestStatus.OK, toXContent); - } - - public static void created(final RestChannel channel, final String message) { - response(channel, RestStatus.CREATED, message); - } - - public static void methodNotImplemented(final RestChannel channel, final RestRequest.Method method) { - notImplemented(channel, "Method " + method.name() + " not supported for this action."); - } - - public static void notImplemented(final RestChannel channel, final String message) { - response(channel, RestStatus.NOT_IMPLEMENTED, message); - } - - public static void notFound(final RestChannel channel, final String message) { - response(channel, RestStatus.NOT_FOUND, message); - } - - public static void conflict(final RestChannel channel, final String message) { - response(channel, RestStatus.CONFLICT, message); - } - - public static void internalServerError(final RestChannel channel, final String message) { - response(channel, RestStatus.INTERNAL_SERVER_ERROR, message); - } - - public static void forbidden(final RestChannel channel, final String message) { - response(channel, RestStatus.FORBIDDEN, message); - } - - public static void badRequest(final RestChannel channel, final String message) { - response(channel, RestStatus.BAD_REQUEST, message); - } - - public static void unauthorized(final RestChannel channel) { - response(channel, RestStatus.UNAUTHORIZED, "Unauthorized"); - } - - public static void response(RestChannel channel, RestStatus status, String message) { - response(channel, status, payload(status, message)); - } - - public static void response(final RestChannel channel, final RestStatus status, final ToXContent toXContent) { - try (final var builder = channel.newBuilder()) { - toXContent.toXContent(builder, ToXContent.EMPTY_PARAMS); - channel.sendResponse(new BytesRestResponse(status, builder)); - } catch (final IOException ioe) { - throw ExceptionsHelper.convertToOpenSearchException(ioe); - } - } - - public static ToXContent forbiddenMessage(final String message) { - return payload(RestStatus.FORBIDDEN, message); - } - - public static ToXContent badRequestMessage(final String message) { - return payload(RestStatus.BAD_REQUEST, message); - } - - public static ToXContent methodNotImplementedMessage(final RestRequest.Method method) { - return payload(RestStatus.NOT_FOUND, "Method " + method.name() + " not supported for this action."); - } - - public static ToXContent notFoundMessage(final String message) { - return payload(RestStatus.NOT_FOUND, message); - } - - public static ToXContent conflictMessage(final String message) { - return payload(RestStatus.CONFLICT, message); - } - - public static ToXContent payload(final RestStatus status, final String message) { - return (builder, params) -> builder.startObject().field("status", status.name()).field("message", message).endObject(); - } - -} diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RestApiAdminPrivilegesEvaluator.java b/src/main/java/org/opensearch/security/dlic/rest/api/RestApiAdminPrivilegesEvaluator.java index faa0217db2..86ebff59d9 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RestApiAdminPrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RestApiAdminPrivilegesEvaluator.java @@ -21,15 +21,15 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.security.configuration.AdminDNs; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.securityconf.impl.v7.ActionGroupsV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class RestApiAdminPrivilegesEvaluator { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluator.java b/src/main/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluator.java index f1a336986b..b367e2f47c 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluator.java @@ -33,15 +33,15 @@ import org.opensearch.core.common.transport.TransportAddress; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; -import org.opensearch.security.configuration.AdminDNs; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestFactory; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.util.SSLRequestHelper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; // TODO: Make Singleton? diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RolesApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/RolesApiAction.java index 4339a11d96..56f2aa00f6 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RolesApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RolesApiAction.java @@ -38,10 +38,10 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; public class RolesApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/RolesMappingApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/RolesMappingApiAction.java index 58ce27af93..556b3d8a93 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/RolesMappingApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/RolesMappingApiAction.java @@ -31,10 +31,10 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; public class RolesMappingApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityApiDependencies.java b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityApiDependencies.java index 498230423f..073b03a1c6 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityApiDependencies.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityApiDependencies.java @@ -13,10 +13,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.privileges.PrivilegesEvaluator; -import org.opensearch.security.support.ConfigConstants; public class SecurityApiDependencies { private AdminDNs adminDNs; diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiAction.java index 4cb5a2a77e..7f400ee758 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiAction.java @@ -22,19 +22,19 @@ import org.opensearch.common.settings.Settings; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.EndpointValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType; import org.opensearch.security.securityconf.impl.CType; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; import static org.opensearch.security.dlic.rest.api.RequestHandler.methodNotImplementedHandler; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.SECURITY_CONFIG_UPDATE; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class SecurityConfigApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityRestApiActions.java b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityRestApiActions.java index 56d0b4b129..c22dfe1432 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/SecurityRestApiActions.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/SecurityRestApiActions.java @@ -20,7 +20,7 @@ import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.privileges.PrivilegesEvaluator; @@ -30,7 +30,7 @@ import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class SecurityRestApiActions { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/SecuritySSLCertsApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/SecuritySSLCertsApiAction.java index acaa9d0aab..290a6dd65f 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/SecuritySSLCertsApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/SecuritySSLCertsApiAction.java @@ -28,24 +28,25 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.dlic.rest.api.Responses; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.ValidationResult; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.ssl.SslContextHandler; import org.opensearch.security.ssl.SslSettingsManager; import org.opensearch.security.ssl.config.CertType; import org.opensearch.security.ssl.config.Certificate; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.api.Responses.badRequest; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.ok; -import static org.opensearch.security.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequest; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.ok; +import static org.opensearch.security.common.dlic.rest.api.Responses.response; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.CERTS_INFO_ACTION; import static org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator.RELOAD_CERTS_ACTION; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; /** * Rest API action to get SSL certificate information related to http and transport encryption. diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/TenantsApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/TenantsApiAction.java index 6eb2c986a9..990ac3f57e 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/TenantsApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/TenantsApiAction.java @@ -43,9 +43,9 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addLegacyRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addLegacyRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class TenantsApiAction extends AbstractApiAction { diff --git a/src/main/java/org/opensearch/security/dlic/rest/api/WhitelistApiAction.java b/src/main/java/org/opensearch/security/dlic/rest/api/WhitelistApiAction.java index fd71312910..6cc022d311 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/api/WhitelistApiAction.java +++ b/src/main/java/org/opensearch/security/dlic/rest/api/WhitelistApiAction.java @@ -22,7 +22,7 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.threadpool.ThreadPool; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; /** * This class implements GET and PUT operations to manage dynamic WhitelistingSettings. diff --git a/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java b/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java deleted file mode 100644 index 58d6f77d0b..0000000000 --- a/src/main/java/org/opensearch/security/dlic/rest/support/Utils.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.dlic.rest.support; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.lang3.tuple.Pair; - -import org.opensearch.ExceptionsHelper; -import org.opensearch.OpenSearchParseException; -import org.opensearch.SpecialPermission; -import org.opensearch.common.CheckedSupplier; -import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.common.xcontent.XContentHelper; -import org.opensearch.common.xcontent.XContentType; -import org.opensearch.common.xcontent.json.JsonXContent; -import org.opensearch.core.common.Strings; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.rest.NamedRoute; -import org.opensearch.rest.RestHandler.DeprecatedRoute; -import org.opensearch.rest.RestHandler.Route; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; - -import static org.opensearch.core.xcontent.DeprecationHandler.THROW_UNSUPPORTED_OPERATION; -import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; -import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; - -public class Utils { - - public final static String PLUGIN_ROUTE_PREFIX = "/" + PLUGINS_PREFIX; - - @Deprecated - public final static String LEGACY_PLUGIN_ROUTE_PREFIX = "/" + LEGACY_OPENDISTRO_PREFIX; - - public final static String PLUGIN_API_ROUTE_PREFIX = PLUGIN_ROUTE_PREFIX + "/api"; - - @Deprecated - public final static String LEGACY_PLUGIN_API_ROUTE_PREFIX = LEGACY_PLUGIN_ROUTE_PREFIX + "/api"; - - public final static String OPENDISTRO_API_DEPRECATION_MESSAGE = - "[_opendistro/_security] is a deprecated endpoint path. Please use _plugins/_security instead."; - - public final static String PLUGIN_RESOURCE_ROUTE_PREFIX = PLUGIN_ROUTE_PREFIX + "/resources"; - - private static final ObjectMapper internalMapper = new ObjectMapper(); - - public static Map convertJsonToxToStructuredMap(ToXContent jsonContent) { - Map map = null; - try { - final BytesReference bytes = XContentHelper.toXContent(jsonContent, XContentType.JSON, false); - map = XContentHelper.convertToMap(bytes, false, XContentType.JSON).v2(); - } catch (IOException e1) { - throw ExceptionsHelper.convertToOpenSearchException(e1); - } - - return map; - } - - public static Map convertJsonToxToStructuredMap(String jsonContent) { - try ( - XContentParser parser = XContentType.JSON.xContent() - .createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, jsonContent) - ) { - return parser.map(); - } catch (IOException e1) { - throw ExceptionsHelper.convertToOpenSearchException(e1); - } - } - - private static BytesReference convertStructuredMapToBytes(Map structuredMap) { - try { - return BytesReference.bytes(JsonXContent.contentBuilder().map(structuredMap)); - } catch (IOException e) { - throw new OpenSearchParseException("Failed to convert map", e); - } - } - - public static String convertStructuredMapToJson(Map structuredMap) { - try { - return XContentHelper.convertToJson(convertStructuredMapToBytes(structuredMap), false, XContentType.JSON); - } catch (IOException e) { - throw new OpenSearchParseException("Failed to convert map", e); - } - } - - public static JsonNode convertJsonToJackson(BytesReference jsonContent) { - try { - return DefaultObjectMapper.readTree(jsonContent.utf8ToString()); - } catch (IOException e1) { - throw ExceptionsHelper.convertToOpenSearchException(e1); - } - - } - - public static JsonNode toJsonNode(final String content) throws IOException { - return DefaultObjectMapper.readTree(content); - } - - public static Object toConfigObject(final JsonNode content, final Class clazz) throws IOException { - return DefaultObjectMapper.readTree(content, clazz); - } - - public static JsonNode convertJsonToJackson(ToXContent jsonContent, boolean omitDefaults) { - try { - return DefaultObjectMapper.readTree( - Strings.toString( - XContentType.JSON, - jsonContent, - new ToXContent.MapParams(Map.of("omit_defaults", String.valueOf(omitDefaults))) - ) - ); - } catch (IOException e1) { - throw ExceptionsHelper.convertToOpenSearchException(e1); - } - - } - - @SuppressWarnings("removal") - public static byte[] jsonMapToByteArray(Map jsonAsMap) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged((PrivilegedExceptionAction) () -> internalMapper.writeValueAsBytes(jsonAsMap)); - } catch (final PrivilegedActionException e) { - if (e.getCause() instanceof JsonProcessingException) { - throw (JsonProcessingException) e.getCause(); - } else if (e.getCause() instanceof RuntimeException) { - throw (RuntimeException) e.getCause(); - } else { - throw new RuntimeException(e.getCause()); - } - } - } - - @SuppressWarnings("removal") - public static Map byteArrayToMutableJsonMap(byte[] jsonBytes) throws IOException { - - final SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission(new SpecialPermission()); - } - - try { - return AccessController.doPrivileged( - (PrivilegedExceptionAction>) () -> internalMapper.readValue( - jsonBytes, - new TypeReference>() { - } - ) - ); - } catch (final PrivilegedActionException e) { - if (e.getCause() instanceof IOException) { - throw (IOException) e.getCause(); - } else if (e.getCause() instanceof RuntimeException) { - throw (RuntimeException) e.getCause(); - } else { - throw new RuntimeException(e.getCause()); - } - } - } - - /** - * Generate field resource paths - * @param fields fields - * @param prefix prefix path - * @return new set of fields resource paths - */ - public static Set generateFieldResourcePaths(final Set fields, final String prefix) { - return fields.stream().map(field -> prefix + field).collect(ImmutableSet.toImmutableSet()); - } - - /** - * Add prefixes(_plugins/_security/api) to rest API routes - * @param routes routes - * @return new list of API routes prefixed with and _plugins/_security/api - */ - public static List addRoutesPrefix(List routes) { - return addRoutesPrefix(routes, PLUGIN_API_ROUTE_PREFIX); - } - - /** - * Add prefixes(_opendistro/_security/api) to rest API routes - * Deprecated in favor of addRoutesPrefix(List routes) - * @param routes routes - * @return new list of API routes prefixed with and _opendistro/_security/api - */ - @Deprecated - public static List addLegacyRoutesPrefix(List routes) { - return addDeprecatedRoutesPrefix(routes, LEGACY_PLUGIN_API_ROUTE_PREFIX); - } - - /** - * Add customized prefix(_opendistro... and _plugins...)to API rest routes - * @param routes routes - * @param prefixes all api prefix - * @return new list of API routes prefixed with the strings listed in prefixes - * Total number of routes will be expanded len(prefixes) as much comparing to the list passed in - */ - public static List addRoutesPrefix(List routes, final String... prefixes) { - return routes.stream().flatMap(r -> Arrays.stream(prefixes).map(p -> { - if (r instanceof NamedRoute) { - NamedRoute nr = (NamedRoute) r; - return new NamedRoute.Builder().method(nr.getMethod()) - .path(p + nr.getPath()) - .uniqueName(nr.name()) - .legacyActionNames(nr.actionNames()) - .build(); - } - return new Route(r.getMethod(), p + r.getPath()); - })).collect(ImmutableList.toImmutableList()); - } - - /** - * Add prefixes(_plugins...) to rest API routes - * @param deprecatedRoutes Routes being deprecated - * @return new list of API routes prefixed with _opendistro... and _plugins... - *Total number of routes is expanded as twice as the number of routes passed in - */ - public static List addDeprecatedRoutesPrefix(List deprecatedRoutes) { - return addDeprecatedRoutesPrefix(deprecatedRoutes, LEGACY_PLUGIN_API_ROUTE_PREFIX, PLUGIN_API_ROUTE_PREFIX); - } - - /** - * Add customized prefix(_opendistro... and _plugins...)to API rest routes - * @param deprecatedRoutes Routes being deprecated - * @param prefixes all api prefix - * @return new list of API routes prefixed with the strings listed in prefixes - * Total number of routes will be expanded len(prefixes) as much comparing to the list passed in - */ - public static List addDeprecatedRoutesPrefix(List deprecatedRoutes, final String... prefixes) { - return deprecatedRoutes.stream() - .flatMap(r -> Arrays.stream(prefixes).map(p -> new DeprecatedRoute(r.getMethod(), p + r.getPath(), r.getDeprecationMessage()))) - .collect(ImmutableList.toImmutableList()); - } - - public static Pair userAndRemoteAddressFrom(final ThreadContext threadContext) { - final User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); - final TransportAddress remoteAddress = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); - return Pair.of(user, remoteAddress); - } - - public static T withIOException(final CheckedSupplier action) { - try { - return action.get(); - } catch (final IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - -} diff --git a/src/main/java/org/opensearch/security/dlic/rest/validation/EndpointValidator.java b/src/main/java/org/opensearch/security/dlic/rest/validation/EndpointValidator.java index 17c8b1f2ba..7a13c6698b 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/validation/EndpointValidator.java +++ b/src/main/java/org/opensearch/security/dlic/rest/validation/EndpointValidator.java @@ -14,15 +14,15 @@ import java.util.Objects; import org.opensearch.core.rest.RestStatus; +import org.opensearch.security.common.dlic.rest.support.Utils; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator; import org.opensearch.security.dlic.rest.api.SecurityConfiguration; -import org.opensearch.security.dlic.rest.support.Utils; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import static org.opensearch.security.dlic.rest.api.Responses.badRequestMessage; -import static org.opensearch.security.dlic.rest.api.Responses.forbiddenMessage; -import static org.opensearch.security.dlic.rest.api.Responses.notFoundMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.badRequestMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.forbiddenMessage; +import static org.opensearch.security.common.dlic.rest.api.Responses.notFoundMessage; public interface EndpointValidator { diff --git a/src/main/java/org/opensearch/security/dlic/rest/validation/PasswordValidator.java b/src/main/java/org/opensearch/security/dlic/rest/validation/PasswordValidator.java index ebb3a4e88b..5c080007c3 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/validation/PasswordValidator.java +++ b/src/main/java/org/opensearch/security/dlic/rest/validation/PasswordValidator.java @@ -29,9 +29,9 @@ import com.nulabinc.zxcvbn.Zxcvbn; import com.nulabinc.zxcvbn.matchers.Match; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX; public class PasswordValidator { diff --git a/src/main/java/org/opensearch/security/dlic/rest/validation/RequestContentValidator.java b/src/main/java/org/opensearch/security/dlic/rest/validation/RequestContentValidator.java index 097b953690..a44cebb58c 100644 --- a/src/main/java/org/opensearch/security/dlic/rest/validation/RequestContentValidator.java +++ b/src/main/java/org/opensearch/security/dlic/rest/validation/RequestContentValidator.java @@ -31,12 +31,12 @@ import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import com.flipkart.zjsonpatch.JsonDiff; -import static org.opensearch.security.dlic.rest.api.Responses.payload; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE; +import static org.opensearch.security.common.dlic.rest.api.Responses.payload; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE; public class RequestContentValidator implements ToXContent { diff --git a/src/main/java/org/opensearch/security/filter/SecurityFilter.java b/src/main/java/org/opensearch/security/filter/SecurityFilter.java index 6b23fb6b53..7d2fe83753 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityFilter.java @@ -77,8 +77,11 @@ import org.opensearch.security.auditlog.AuditLog.Origin; import org.opensearch.security.auth.RolesInjector; import org.opensearch.security.auth.UserInjector; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.configuration.AdminDNs; import org.opensearch.security.configuration.CompatConfig; import org.opensearch.security.configuration.DlsFlsRequestValve; import org.opensearch.security.http.XFFResolver; @@ -87,11 +90,8 @@ import org.opensearch.security.privileges.PrivilegesEvaluatorResponse; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; import org.opensearch.security.support.SourceFieldsContext; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; diff --git a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java index 0f1b8ce678..5eaab86e3f 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java @@ -49,7 +49,9 @@ import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.AuditLog.Origin; import org.opensearch.security.auth.BackendRegistry; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.CompatConfig; import org.opensearch.security.dlic.rest.api.AllowlistApiAction; import org.opensearch.security.privileges.PrivilegesEvaluatorResponse; @@ -61,9 +63,7 @@ import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.ssl.util.SSLRequestHelper; import org.opensearch.security.ssl.util.SSLRequestHelper.SSLInfo; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HTTPHelper; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; @@ -72,7 +72,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_INITIATING_USER; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_INITIATING_USER; public class SecurityRestFilter { diff --git a/src/main/java/org/opensearch/security/hasher/PasswordHasherFactory.java b/src/main/java/org/opensearch/security/hasher/PasswordHasherFactory.java index ad2dc7eb57..34c21d5411 100644 --- a/src/main/java/org/opensearch/security/hasher/PasswordHasherFactory.java +++ b/src/main/java/org/opensearch/security/hasher/PasswordHasherFactory.java @@ -14,10 +14,10 @@ import java.util.Set; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; -import static org.opensearch.security.support.ConfigConstants.BCRYPT; -import static org.opensearch.security.support.ConfigConstants.PBKDF2; +import static org.opensearch.security.common.support.ConfigConstants.BCRYPT; +import static org.opensearch.security.common.support.ConfigConstants.PBKDF2; public class PasswordHasherFactory { diff --git a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java index 4aec26db3d..f8fa09a1e5 100644 --- a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java @@ -37,10 +37,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; import org.opensearch.security.support.HTTPHelper; -import org.opensearch.security.user.AuthCredentials; //TODO FUTURE allow only if protocol==https public class HTTPBasicAuthenticator implements HTTPAuthenticator { diff --git a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java index 684131b3e5..c42e2e0559 100644 --- a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java @@ -42,10 +42,10 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.Strings; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.AuthCredentials; public class HTTPClientCertAuthenticator implements HTTPAuthenticator { diff --git a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java index e49248a0dc..a166a3bf91 100644 --- a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java @@ -37,10 +37,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.AuthCredentials; import static java.util.function.Predicate.not; diff --git a/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java b/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java index 111eff7a33..5c2ba25fa4 100644 --- a/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java @@ -32,13 +32,13 @@ import org.opensearch.SpecialPermission; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auth.HTTPAuthenticator; import org.opensearch.security.authtoken.jwt.EncryptionDecryptionUtil; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; import org.opensearch.security.ssl.util.ExceptionUtils; -import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.KeyUtils; import io.jsonwebtoken.Claims; diff --git a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java index 7b76a82c42..c19f8f26d5 100644 --- a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java +++ b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java @@ -53,8 +53,8 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.filter.SecurityRequest; -import org.opensearch.security.support.ConfigConstants; final class RemoteIpDetector { diff --git a/src/main/java/org/opensearch/security/http/XFFResolver.java b/src/main/java/org/opensearch/security/http/XFFResolver.java index 0a3d183341..e8da0d9d05 100644 --- a/src/main/java/org/opensearch/security/http/XFFResolver.java +++ b/src/main/java/org/opensearch/security/http/XFFResolver.java @@ -34,9 +34,9 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.transport.TransportAddress; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.greenrobot.eventbus.Subscribe; diff --git a/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java b/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java index 9a16e6c61b..9bbf77daa5 100644 --- a/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java @@ -37,9 +37,9 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.Strings; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.http.HTTPProxyAuthenticator; -import org.opensearch.security.user.AuthCredentials; public class HTTPExtendedProxyAuthenticator extends HTTPProxyAuthenticator { diff --git a/src/main/java/org/opensearch/security/identity/ContextProvidingPluginSubject.java b/src/main/java/org/opensearch/security/identity/ContextProvidingPluginSubject.java index ab6dddceba..1fc580c1da 100644 --- a/src/main/java/org/opensearch/security/identity/ContextProvidingPluginSubject.java +++ b/src/main/java/org/opensearch/security/identity/ContextProvidingPluginSubject.java @@ -17,8 +17,8 @@ import org.opensearch.identity.NamedPrincipal; import org.opensearch.identity.PluginSubject; import org.opensearch.plugins.Plugin; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.threadpool.ThreadPool; public class ContextProvidingPluginSubject implements PluginSubject { diff --git a/src/main/java/org/opensearch/security/identity/SecurityTokenManager.java b/src/main/java/org/opensearch/security/identity/SecurityTokenManager.java index 8a0c3e85f1..827c301967 100644 --- a/src/main/java/org/opensearch/security/identity/SecurityTokenManager.java +++ b/src/main/java/org/opensearch/security/identity/SecurityTokenManager.java @@ -29,10 +29,10 @@ import org.opensearch.identity.tokens.TokenManager; import org.opensearch.security.authtoken.jwt.ExpiringBearerAuthToken; import org.opensearch.security.authtoken.jwt.JwtVendor; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.securityconf.ConfigModel; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.security.user.UserService; import org.opensearch.threadpool.ThreadPool; diff --git a/src/main/java/org/opensearch/security/privileges/ActionPrivileges.java b/src/main/java/org/opensearch/security/privileges/ActionPrivileges.java index eb560ed901..a76b1bb6ff 100644 --- a/src/main/java/org/opensearch/security/privileges/ActionPrivileges.java +++ b/src/main/java/org/opensearch/security/privileges/ActionPrivileges.java @@ -35,11 +35,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.unit.ByteSizeUnit; import org.opensearch.core.common.unit.ByteSizeValue; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.FlattenedActionGroups; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.WildcardMatcher; import com.selectivem.collections.CheckTable; import com.selectivem.collections.CompactMapGroupBuilder; diff --git a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java index 6e41857737..d6087f0645 100644 --- a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java +++ b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java @@ -18,7 +18,7 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; /** * Defines which indices and documents are implicitly accessible although a user does not have diff --git a/src/main/java/org/opensearch/security/privileges/IndexPattern.java b/src/main/java/org/opensearch/security/privileges/IndexPattern.java index d5d419f72b..df8b3b1799 100644 --- a/src/main/java/org/opensearch/security/privileges/IndexPattern.java +++ b/src/main/java/org/opensearch/security/privileges/IndexPattern.java @@ -22,7 +22,7 @@ import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.support.WildcardMatcher; /** * Aggregates index patterns defined in roles and segments them into patterns using template expressions ("index_${user.name}"), diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluationContext.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluationContext.java index f7e5d6de7d..9aa5b9d94f 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluationContext.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluationContext.java @@ -20,9 +20,9 @@ import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; /** diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java index 158a5d0a48..cc0d4cc971 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java @@ -88,6 +88,9 @@ import org.opensearch.index.reindex.ReindexAction; import org.opensearch.script.mustache.RenderSearchTemplateAction; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.resolver.IndexResolverReplacer; @@ -101,16 +104,13 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.ActionGroupsV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.greenrobot.eventbus.Subscribe; import static org.opensearch.security.OpenSearchSecurityPlugin.traceAction; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT; public class PrivilegesEvaluator { diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java index 750c7d2b41..b6f5255556 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java @@ -33,9 +33,9 @@ import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer.Resolved; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/privileges/ProtectedIndexAccessEvaluator.java b/src/main/java/org/opensearch/security/privileges/ProtectedIndexAccessEvaluator.java index 877e6fd787..bcb1aac375 100644 --- a/src/main/java/org/opensearch/security/privileges/ProtectedIndexAccessEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/ProtectedIndexAccessEvaluator.java @@ -23,9 +23,9 @@ import org.opensearch.action.search.SearchRequest; import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.resolver.IndexResolverReplacer; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.tasks.Task; public class ProtectedIndexAccessEvaluator { diff --git a/src/main/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluator.java index b1f994163c..f47e955d2a 100644 --- a/src/main/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluator.java @@ -16,7 +16,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; public class RestLayerPrivilegesEvaluator { protected final Logger log = LogManager.getLogger(this.getClass()); diff --git a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java index 23612e1a52..62ecd95f6d 100644 --- a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java @@ -35,8 +35,8 @@ import org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.configuration.ClusterInfoHolder; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SnapshotRestoreHelper; import org.opensearch.tasks.Task; diff --git a/src/main/java/org/opensearch/security/privileges/SystemIndexAccessEvaluator.java b/src/main/java/org/opensearch/security/privileges/SystemIndexAccessEvaluator.java index ba03ff2f25..d0d3b4a03f 100644 --- a/src/main/java/org/opensearch/security/privileges/SystemIndexAccessEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SystemIndexAccessEvaluator.java @@ -42,11 +42,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.indices.SystemIndexRegistry; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.resolver.IndexResolverReplacer.Resolved; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; /** diff --git a/src/main/java/org/opensearch/security/privileges/UserAttributes.java b/src/main/java/org/opensearch/security/privileges/UserAttributes.java index a1a949d96c..a1f7fdbf77 100644 --- a/src/main/java/org/opensearch/security/privileges/UserAttributes.java +++ b/src/main/java/org/opensearch/security/privileges/UserAttributes.java @@ -17,7 +17,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; /** * Support for interpolating user attributes used in index patterns and DLS queries. diff --git a/src/main/java/org/opensearch/security/privileges/WellKnownActions.java b/src/main/java/org/opensearch/security/privileges/WellKnownActions.java index af4f0bb025..3c3477665a 100644 --- a/src/main/java/org/opensearch/security/privileges/WellKnownActions.java +++ b/src/main/java/org/opensearch/security/privileges/WellKnownActions.java @@ -39,7 +39,7 @@ import org.opensearch.action.update.UpdateAction; import org.opensearch.index.reindex.DeleteByQueryAction; import org.opensearch.index.reindex.UpdateByQueryAction; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; /** * This class lists so-called "well-known actions". These are taken into account when creating the pre-computed diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/AbstractRuleBasedPrivileges.java b/src/main/java/org/opensearch/security/privileges/dlsfls/AbstractRuleBasedPrivileges.java index 43baf8090d..a16d80b3f4 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/AbstractRuleBasedPrivileges.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/AbstractRuleBasedPrivileges.java @@ -26,6 +26,8 @@ import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.privileges.IndexPattern; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; @@ -33,8 +35,6 @@ import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import com.selectivem.collections.CompactMapGroupBuilder; import com.selectivem.collections.DeduplicatingCompactSubSetBuilder; diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsBaseContext.java b/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsBaseContext.java index 8a27fef255..11980b33ff 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsBaseContext.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsBaseContext.java @@ -11,12 +11,12 @@ package org.opensearch.security.privileges.dlsfls; import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluator; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; -import org.opensearch.security.user.User; /** * Node global context data for DLS/FLS. The lifecycle of an instance of this class is equal to the lifecycle of a running node. diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeaders.java b/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeaders.java index b4e35d96cc..be72c2c4a8 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeaders.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/DlsFlsLegacyHeaders.java @@ -24,10 +24,10 @@ import org.opensearch.cluster.metadata.Metadata; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluationException; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; import org.opensearch.transport.Transport; import org.opensearch.transport.TransportRequest; diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java index b16aa7b616..42e4ec4efd 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldMasking.java @@ -29,14 +29,14 @@ import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.configuration.Salt; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluationException; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import com.rfksystems.blake2b.Blake2b; diff --git a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldPrivileges.java b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldPrivileges.java index 83eab0f13a..185ec1fd93 100644 --- a/src/main/java/org/opensearch/security/privileges/dlsfls/FieldPrivileges.java +++ b/src/main/java/org/opensearch/security/privileges/dlsfls/FieldPrivileges.java @@ -24,12 +24,12 @@ import org.opensearch.cluster.metadata.IndexAbstraction; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.privileges.PrivilegesConfigurationValidationException; import org.opensearch.security.privileges.PrivilegesEvaluationContext; import org.opensearch.security.privileges.PrivilegesEvaluationException; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.WildcardMatcher; /** * This class converts role configuration into pre-computed, optimized data structures for checking FLS privileges. diff --git a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java index 9fe7eaa95c..2188efc1ef 100644 --- a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java +++ b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java @@ -90,10 +90,10 @@ import org.opensearch.index.IndexNotFoundException; import org.opensearch.index.reindex.ReindexRequest; import org.opensearch.security.OpenSearchSecurityPlugin; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.securityconf.DynamicConfigModel; import org.opensearch.security.support.SnapshotRestoreHelper; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.snapshots.SnapshotInfo; import org.opensearch.transport.RemoteClusterService; import org.opensearch.transport.TransportRequest; diff --git a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java index 1249994dac..c39a9a6fe6 100644 --- a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java @@ -42,18 +42,18 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestController; import org.opensearch.rest.RestRequest; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluator; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class DashboardsInfoAction extends BaseRestHandler { diff --git a/src/main/java/org/opensearch/security/rest/SecurityConfigUpdateAction.java b/src/main/java/org/opensearch/security/rest/SecurityConfigUpdateAction.java index d6d3843566..14285b198c 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityConfigUpdateAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityConfigUpdateAction.java @@ -27,20 +27,20 @@ import org.opensearch.rest.action.RestActions.NodesResponseRestListener; import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.filter.SecurityRequestFactory; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.util.SSLRequestHelper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.PUT; -import static org.opensearch.security.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class SecurityConfigUpdateAction extends BaseRestHandler { diff --git a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java index 892f48d892..5be18282d6 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java @@ -44,11 +44,11 @@ import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class SecurityHealthAction extends BaseRestHandler { private static final List routes = addRoutesPrefix( diff --git a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java index 1080a8e60c..3f818be8ce 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java @@ -48,20 +48,20 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestController; import org.opensearch.rest.RestRequest; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class SecurityInfoAction extends BaseRestHandler { private static final List routes = addRoutesPrefix( diff --git a/src/main/java/org/opensearch/security/rest/SecurityWhoAmIAction.java b/src/main/java/org/opensearch/security/rest/SecurityWhoAmIAction.java index 55765e3805..714d9986e9 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityWhoAmIAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityWhoAmIAction.java @@ -30,19 +30,19 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestController; import org.opensearch.rest.RestRequest; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.filter.SecurityRequestFactory; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.util.SSLRequestHelper; import org.opensearch.security.ssl.util.SSLRequestHelper.SSLInfo; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class SecurityWhoAmIAction extends BaseRestHandler { diff --git a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java index b2c0566e3d..3ca32c7766 100644 --- a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java @@ -47,25 +47,25 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestController; import org.opensearch.rest.RestRequest; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.securityconf.DynamicConfigFactory; import org.opensearch.security.securityconf.RoleMappings; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.node.NodeClient; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; -import static org.opensearch.security.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; -import static org.opensearch.security.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.LEGACY_PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.OPENDISTRO_API_DEPRECATION_MESSAGE; +import static org.opensearch.security.common.dlic.rest.support.Utils.PLUGIN_ROUTE_PREFIX; +import static org.opensearch.security.common.dlic.rest.support.Utils.addDeprecatedRoutesPrefix; +import static org.opensearch.security.common.dlic.rest.support.Utils.addRoutesPrefix; public class TenantInfoAction extends BaseRestHandler { private static final List routes = addRoutesPrefix( diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModel.java b/src/main/java/org/opensearch/security/securityconf/ConfigModel.java index 7429a2c776..29781a08e1 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModel.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModel.java @@ -30,7 +30,7 @@ import java.util.Set; import org.opensearch.core.common.transport.TransportAddress; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; public abstract class ConfigModel { diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java index 9d6dafc857..16d77f82f1 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java @@ -45,16 +45,16 @@ import org.opensearch.common.collect.Tuple; import org.opensearch.common.settings.Settings; import org.opensearch.core.common.transport.TransportAddress; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.User; import org.opensearch.security.privileges.UserAttributes; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.ActionGroupsV7; import org.opensearch.security.securityconf.impl.v7.RoleMappingsV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; import org.opensearch.security.securityconf.impl.v7.TenantV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HostResolverMode; -import org.opensearch.security.support.WildcardMatcher; -import org.opensearch.security.user.User; public class ConfigModelV7 extends ConfigModel { diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java index c427a46685..02bdd57b97 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java @@ -41,9 +41,11 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; import org.opensearch.security.auth.internal.InternalAuthenticationBackend; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.configuration.ConfigurationChangeListener; import org.opensearch.security.configuration.ConfigurationMap; @@ -61,8 +63,6 @@ import org.opensearch.security.securityconf.impl.v7.RoleMappingsV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; import org.opensearch.security.securityconf.impl.v7.TenantV7; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.client.Client; diff --git a/src/main/java/org/opensearch/security/securityconf/NodesDnModel.java b/src/main/java/org/opensearch/security/securityconf/NodesDnModel.java index b7d556447c..87b18fa4b3 100644 --- a/src/main/java/org/opensearch/security/securityconf/NodesDnModel.java +++ b/src/main/java/org/opensearch/security/securityconf/NodesDnModel.java @@ -13,7 +13,7 @@ import java.util.Map; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.support.WildcardMatcher; public abstract class NodesDnModel { public abstract Map getNodesDn(); diff --git a/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java b/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java index 790f39d12b..26ba4eacf0 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java @@ -45,7 +45,7 @@ import org.opensearch.ExceptionsHelper; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.Hashed; import org.opensearch.security.securityconf.Hideable; import org.opensearch.security.securityconf.StaticDefinable; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java index 77fb973a52..3eb84504b3 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java @@ -43,8 +43,8 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auth.internal.InternalAuthenticationBackend; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.DashboardSignInOption; import org.opensearch.security.setting.DeprecatedSettings; diff --git a/src/main/java/org/opensearch/security/setting/TransportPassiveAuthSetting.java b/src/main/java/org/opensearch/security/setting/TransportPassiveAuthSetting.java index 89c96b423a..b84e8c1db3 100644 --- a/src/main/java/org/opensearch/security/setting/TransportPassiveAuthSetting.java +++ b/src/main/java/org/opensearch/security/setting/TransportPassiveAuthSetting.java @@ -13,7 +13,7 @@ import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; public class TransportPassiveAuthSetting extends OpensearchDynamicSetting { diff --git a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java index 7068f40dd7..90fe79e892 100644 --- a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java +++ b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java @@ -71,8 +71,8 @@ import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; import org.opensearch.script.ScriptService; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.NonValidatingObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.filter.SecurityRestFilter; import org.opensearch.security.ssl.http.netty.ValidatingDispatcher; import org.opensearch.security.ssl.rest.SecuritySSLInfoAction; diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java b/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java index ed06f312b6..546dd9488a 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/Netty4HttpRequestHeaderVerifier.java @@ -16,6 +16,7 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.http.netty4.Netty4HttpChannel; import org.opensearch.http.netty4.Netty4HttpServerTransport; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.filter.SecurityRequestChannel; import org.opensearch.security.filter.SecurityRequestChannelUnsupported; import org.opensearch.security.filter.SecurityRequestFactory; @@ -24,7 +25,6 @@ import org.opensearch.security.filter.SecurityRestUtils; import org.opensearch.security.ssl.OpenSearchSecuritySSLPlugin; import org.opensearch.security.ssl.transport.SSLConfig; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import io.netty.channel.ChannelHandler.Sharable; diff --git a/src/main/java/org/opensearch/security/ssl/transport/SSLConfig.java b/src/main/java/org/opensearch/security/ssl/transport/SSLConfig.java index d30e45022a..a54a999129 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SSLConfig.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SSLConfig.java @@ -16,7 +16,7 @@ import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.support.SecuritySettings; public class SSLConfig { diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java index 7002171595..0b9ea22286 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java @@ -30,10 +30,10 @@ import org.opensearch.ExceptionsHelper; import org.opensearch.OpenSearchException; import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.SslExceptionHandler; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.ssl.util.SSLRequestHelper; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SerializationFormat; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; diff --git a/src/main/java/org/opensearch/security/support/Base64CustomHelper.java b/src/main/java/org/opensearch/security/support/Base64CustomHelper.java index 30fab31907..879a3ec61a 100644 --- a/src/main/java/org/opensearch/security/support/Base64CustomHelper.java +++ b/src/main/java/org/opensearch/security/support/Base64CustomHelper.java @@ -27,7 +27,7 @@ import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.Writeable; import org.opensearch.security.auth.UserInjector; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java deleted file mode 100644 index 346437e775..0000000000 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.support; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -import org.opensearch.common.settings.Settings; -import org.opensearch.security.auditlog.impl.AuditCategory; - -import com.password4j.types.Hmac; - -public class ConfigConstants { - - public static final String OPENDISTRO_SECURITY_CONFIG_PREFIX = "_opendistro_security_"; - public static final String SECURITY_SETTINGS_PREFIX = "plugins.security."; - - public static final String OPENDISTRO_SECURITY_CHANNEL_TYPE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "channel_type"; - - public static final String OPENDISTRO_SECURITY_ORIGIN = OPENDISTRO_SECURITY_CONFIG_PREFIX + "origin"; - public static final String OPENDISTRO_SECURITY_ORIGIN_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "origin_header"; - - public static final String OPENDISTRO_SECURITY_DLS_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_query"; - - public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "dls_filter_level_query"; - public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "dls_filter_level_query_t"; - - public static final String OPENDISTRO_SECURITY_DLS_MODE_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_mode"; - public static final String OPENDISTRO_SECURITY_DLS_MODE_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_mode_t"; - - public static final String OPENDISTRO_SECURITY_FLS_FIELDS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "fls_fields"; - - public static final String OPENDISTRO_SECURITY_MASKED_FIELD_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "masked_fields"; - - public static final String OPENDISTRO_SECURITY_DOC_ALLOWLIST_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "doc_allowlist"; - public static final String OPENDISTRO_SECURITY_DOC_ALLOWLIST_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "doc_allowlist_t"; - - public static final String OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "filter_level_dls_done"; - - public static final String OPENDISTRO_SECURITY_DLS_QUERY_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "dls_query_ccs"; - - public static final String OPENDISTRO_SECURITY_FLS_FIELDS_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "fls_fields_ccs"; - - public static final String OPENDISTRO_SECURITY_MASKED_FIELD_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "masked_fields_ccs"; - - public static final String OPENDISTRO_SECURITY_CONF_REQUEST_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "conf_request"; - - public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS = OPENDISTRO_SECURITY_CONFIG_PREFIX + "remote_address"; - public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "remote_address_header"; - - public static final String OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "initial_action_class_header"; - - /** - * Set by SSL plugin for https requests only - */ - public static final String OPENDISTRO_SECURITY_SSL_PEER_CERTIFICATES = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_peer_certificates"; - - /** - * Set by SSL plugin for https requests only - */ - public static final String OPENDISTRO_SECURITY_SSL_PRINCIPAL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_principal"; - - /** - * If this is set to TRUE then the request comes from a Server Node (fully trust) - * Its expected that there is a _opendistro_security_user attached as header - */ - public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_INTERCLUSTER_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "ssl_transport_intercluster_request"; - - public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "ssl_transport_trustedcluster_request"; - - // CS-SUPPRESS-SINGLE: RegexpSingleline Extensions manager used to allow/disallow TLS connections to extensions - public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENSION_REQUEST = OPENDISTRO_SECURITY_CONFIG_PREFIX - + "ssl_transport_extension_request"; - // CS-ENFORCE-SINGLE - - /** - * Set by the SSL plugin, this is the peer node certificate on the transport layer - */ - public static final String OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "ssl_transport_principal"; - - public static final String OPENDISTRO_SECURITY_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user"; - public static final String OPENDISTRO_SECURITY_USER_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user_header"; - - // persistent header. This header is set once and cannot be stashed - public static final String OPENDISTRO_SECURITY_AUTHENTICATED_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "authenticated_user"; - - public static final String OPENDISTRO_SECURITY_USER_INFO_THREAD_CONTEXT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "user_info"; - - public static final String OPENDISTRO_SECURITY_INITIATING_USER = OPENDISTRO_SECURITY_CONFIG_PREFIX + "_initiating_user"; - - public static final String OPENDISTRO_SECURITY_INJECTED_USER = "injected_user"; - public static final String OPENDISTRO_SECURITY_INJECTED_USER_HEADER = "injected_user_header"; - - public static final String OPENDISTRO_SECURITY_XFF_DONE = OPENDISTRO_SECURITY_CONFIG_PREFIX + "xff_done"; - - public static final String SSO_LOGOUT_URL = OPENDISTRO_SECURITY_CONFIG_PREFIX + "sso_logout_url"; - - public static final String OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX = ".opendistro_security"; - - public static final String SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = SECURITY_SETTINGS_PREFIX + "enable_snapshot_restore_privilege"; - public static final boolean SECURITY_DEFAULT_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = true; - - public static final String SECURITY_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = SECURITY_SETTINGS_PREFIX - + "check_snapshot_restore_write_privileges"; - public static final boolean SECURITY_DEFAULT_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES = true; - public static final Set SECURITY_SNAPSHOT_RESTORE_NEEDED_WRITE_PRIVILEGES = Collections.unmodifiableSet( - new HashSet(Arrays.asList("indices:admin/create", "indices:data/write/index" - // "indices:data/write/bulk" - )) - ); - - public static final String SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX - + "cert.intercluster_request_evaluator_class"; - public static final String OPENDISTRO_SECURITY_ACTION_NAME = OPENDISTRO_SECURITY_CONFIG_PREFIX + "action_name"; - - public static final String SECURITY_AUTHCZ_ADMIN_DN = SECURITY_SETTINGS_PREFIX + "authcz.admin_dn"; - public static final String SECURITY_CONFIG_INDEX_NAME = SECURITY_SETTINGS_PREFIX + "config_index_name"; - public static final String SECURITY_AUTHCZ_IMPERSONATION_DN = SECURITY_SETTINGS_PREFIX + "authcz.impersonation_dn"; - public static final String SECURITY_AUTHCZ_REST_IMPERSONATION_USERS = SECURITY_SETTINGS_PREFIX + "authcz.rest_impersonation_user"; - - public static final String BCRYPT = "bcrypt"; - public static final String PBKDF2 = "pbkdf2"; - - public static final String SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.rounds"; - public static final int SECURITY_PASSWORD_HASHING_BCRYPT_ROUNDS_DEFAULT = 12; - public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR = SECURITY_SETTINGS_PREFIX + "password.hashing.bcrypt.minor"; - public static final String SECURITY_PASSWORD_HASHING_BCRYPT_MINOR_DEFAULT = "Y"; - - public static final String SECURITY_PASSWORD_HASHING_ALGORITHM = SECURITY_SETTINGS_PREFIX + "password.hashing.algorithm"; - public static final String SECURITY_PASSWORD_HASHING_ALGORITHM_DEFAULT = BCRYPT; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS = SECURITY_SETTINGS_PREFIX - + "password.hashing.pbkdf2.iterations"; - public static final int SECURITY_PASSWORD_HASHING_PBKDF2_ITERATIONS_DEFAULT = 600_000; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.length"; - public static final int SECURITY_PASSWORD_HASHING_PBKDF2_LENGTH_DEFAULT = 256; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION = SECURITY_SETTINGS_PREFIX + "password.hashing.pbkdf2.function"; - public static final String SECURITY_PASSWORD_HASHING_PBKDF2_FUNCTION_DEFAULT = Hmac.SHA256.name(); - - public static final String SECURITY_AUDIT_TYPE_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.type"; - public static final String SECURITY_AUDIT_CONFIG_DEFAULT = SECURITY_SETTINGS_PREFIX + "audit.config"; - public static final String SECURITY_AUDIT_CONFIG_ROUTES = SECURITY_SETTINGS_PREFIX + "audit.routes"; - public static final String SECURITY_AUDIT_CONFIG_ENDPOINTS = SECURITY_SETTINGS_PREFIX + "audit.endpoints"; - public static final String SECURITY_AUDIT_THREADPOOL_SIZE = SECURITY_SETTINGS_PREFIX + "audit.threadpool.size"; - public static final String SECURITY_AUDIT_THREADPOOL_MAX_QUEUE_LEN = SECURITY_SETTINGS_PREFIX + "audit.threadpool.max_queue_len"; - public static final String OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY = "opendistro_security.audit.log_request_body"; - public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES = "opendistro_security.audit.resolve_indices"; - public static final String OPENDISTRO_SECURITY_AUDIT_ENABLE_REST = "opendistro_security.audit.enable_rest"; - public static final String OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT = "opendistro_security.audit.enable_transport"; - public static final String OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES = - "opendistro_security.audit.config.disabled_transport_categories"; - public static final String OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES = - "opendistro_security.audit.config.disabled_rest_categories"; - public static final List OPENDISTRO_SECURITY_AUDIT_DISABLED_CATEGORIES_DEFAULT = ImmutableList.of( - AuditCategory.AUTHENTICATED.toString(), - AuditCategory.GRANTED_PRIVILEGES.toString() - ); - public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS = "opendistro_security.audit.ignore_users"; - public static final String OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS = "opendistro_security.audit.ignore_requests"; - public static final String SECURITY_AUDIT_IGNORE_HEADERS = SECURITY_SETTINGS_PREFIX + "audit.ignore_headers"; - public static final String OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS = "opendistro_security.audit.resolve_bulk_requests"; - public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_VERIFY_HOSTNAMES_DEFAULT = true; - public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_ENABLE_SSL_CLIENT_AUTH_DEFAULT = false; - public static final String OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS = "opendistro_security.audit.exclude_sensitive_headers"; - - public static final String SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX = SECURITY_SETTINGS_PREFIX + "audit.config."; - - // Internal Opensearch data_stream - public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_NAME = "data_stream.name"; - public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_MANAGE = "data_stream.template.manage"; - public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NAME = "data_stream.template.name"; - public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_REPLICAS = "data_stream.template.number_of_replicas"; - public static final String SECURITY_AUDIT_OPENSEARCH_DATASTREAM_TEMPLATE_NUMBER_OF_SHARDS = "data_stream.template.number_of_shards"; - - // Internal / External OpenSearch - public static final String SECURITY_AUDIT_OPENSEARCH_INDEX = "index"; - public static final String SECURITY_AUDIT_OPENSEARCH_TYPE = "type"; - - // External OpenSearch - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_HTTP_ENDPOINTS = "http_endpoints"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME = "username"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD = "password"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL = "enable_ssl"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_VERIFY_HOSTNAMES = "verify_hostnames"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH = "enable_ssl_client_auth"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH = "pemkey_filepath"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_CONTENT = "pemkey_content"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_PASSWORD = "pemkey_password"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH = "pemcert_filepath"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_CONTENT = "pemcert_content"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH = "pemtrustedcas_filepath"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_CONTENT = "pemtrustedcas_content"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_JKS_CERT_ALIAS = "cert_alias"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_CIPHERS = "enabled_ssl_ciphers"; - public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_PROTOCOLS = "enabled_ssl_protocols"; - - // Webhooks - public static final String SECURITY_AUDIT_WEBHOOK_URL = "webhook.url"; - public static final String SECURITY_AUDIT_WEBHOOK_FORMAT = "webhook.format"; - public static final String SECURITY_AUDIT_WEBHOOK_SSL_VERIFY = "webhook.ssl.verify"; - public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_FILEPATH = "webhook.ssl.pemtrustedcas_filepath"; - public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_CONTENT = "webhook.ssl.pemtrustedcas_content"; - - // Log4j - public static final String SECURITY_AUDIT_LOG4J_LOGGER_NAME = "log4j.logger_name"; - public static final String SECURITY_AUDIT_LOG4J_LEVEL = "log4j.level"; - - // retry - public static final String SECURITY_AUDIT_RETRY_COUNT = SECURITY_SETTINGS_PREFIX + "audit.config.retry_count"; - public static final String SECURITY_AUDIT_RETRY_DELAY_MS = SECURITY_SETTINGS_PREFIX + "audit.config.retry_delay_ms"; - - public static final String SECURITY_KERBEROS_KRB5_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.krb5_filepath"; - public static final String SECURITY_KERBEROS_ACCEPTOR_KEYTAB_FILEPATH = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_keytab_filepath"; - public static final String SECURITY_KERBEROS_ACCEPTOR_PRINCIPAL = SECURITY_SETTINGS_PREFIX + "kerberos.acceptor_principal"; - public static final String SECURITY_CERT_OID = SECURITY_SETTINGS_PREFIX + "cert.oid"; - public static final String SECURITY_CERT_INTERCLUSTER_REQUEST_EVALUATOR_CLASS = SECURITY_SETTINGS_PREFIX - + "cert.intercluster_request_evaluator_class"; - public static final String SECURITY_ADVANCED_MODULES_ENABLED = SECURITY_SETTINGS_PREFIX + "advanced_modules_enabled"; - public static final String SECURITY_NODES_DN = SECURITY_SETTINGS_PREFIX + "nodes_dn"; - public static final String SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED = SECURITY_SETTINGS_PREFIX + "nodes_dn_dynamic_config_enabled"; - public static final String SECURITY_DISABLED = SECURITY_SETTINGS_PREFIX + "disabled"; - - public static final String SECURITY_CACHE_TTL_MINUTES = SECURITY_SETTINGS_PREFIX + "cache.ttl_minutes"; - public static final String SECURITY_ALLOW_UNSAFE_DEMOCERTIFICATES = SECURITY_SETTINGS_PREFIX + "allow_unsafe_democertificates"; - public static final String SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX = SECURITY_SETTINGS_PREFIX + "allow_default_init_securityindex"; - - public static final String SECURITY_ALLOW_DEFAULT_INIT_USE_CLUSTER_STATE = SECURITY_SETTINGS_PREFIX - + "allow_default_init_securityindex.use_cluster_state"; - - public static final String SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST = SECURITY_SETTINGS_PREFIX - + "background_init_if_securityindex_not_exist"; - - public static final String SECURITY_ROLES_MAPPING_RESOLUTION = SECURITY_SETTINGS_PREFIX + "roles_mapping_resolution"; - - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_METADATA_ONLY = - "opendistro_security.compliance.history.write.metadata_only"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_METADATA_ONLY = - "opendistro_security.compliance.history.read.metadata_only"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS = - "opendistro_security.compliance.history.read.watched_fields"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES = - "opendistro_security.compliance.history.write.watched_indices"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS = - "opendistro_security.compliance.history.write.log_diffs"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS = - "opendistro_security.compliance.history.read.ignore_users"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS = - "opendistro_security.compliance.history.write.ignore_users"; - public static final String OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED = - "opendistro_security.compliance.history.external_config_enabled"; - public static final String OPENDISTRO_SECURITY_SOURCE_FIELD_CONTEXT = OPENDISTRO_SECURITY_CONFIG_PREFIX + "source_field_context"; - public static final String SECURITY_COMPLIANCE_DISABLE_ANONYMOUS_AUTHENTICATION = SECURITY_SETTINGS_PREFIX - + "compliance.disable_anonymous_authentication"; - public static final String SECURITY_COMPLIANCE_IMMUTABLE_INDICES = SECURITY_SETTINGS_PREFIX + "compliance.immutable_indices"; - public static final String SECURITY_COMPLIANCE_SALT = SECURITY_SETTINGS_PREFIX + "compliance.salt"; - public static final String SECURITY_COMPLIANCE_SALT_DEFAULT = "e1ukloTsQlOgPquJ";// 16 chars - public static final String SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED = - "opendistro_security.compliance.history.internal_config_enabled"; - public static final String SECURITY_SSL_ONLY = SECURITY_SETTINGS_PREFIX + "ssl_only"; - public static final String SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "plugins.security_config.ssl_dual_mode_enabled"; - public static final String SECURITY_SSL_DUAL_MODE_SKIP_SECURITY = OPENDISTRO_SECURITY_CONFIG_PREFIX + "passive_security"; - public static final String LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED = "opendistro_security_config.ssl_dual_mode_enabled"; - public static final String SECURITY_SSL_CERT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX + "ssl_cert_reload_enabled"; - public static final String SECURITY_SSL_CERTIFICATES_HOT_RELOAD_ENABLED = SECURITY_SETTINGS_PREFIX - + "ssl.certificates_hot_reload.enabled"; - public static final String SECURITY_DISABLE_ENVVAR_REPLACEMENT = SECURITY_SETTINGS_PREFIX + "disable_envvar_replacement"; - public static final String SECURITY_DFM_EMPTY_OVERRIDES_ALL = SECURITY_SETTINGS_PREFIX + "dfm_empty_overrides_all"; - - public enum RolesMappingResolution { - MAPPING_ONLY, - BACKENDROLES_ONLY, - BOTH - } - - public static final String SECURITY_FILTER_SECURITYINDEX_FROM_ALL_REQUESTS = SECURITY_SETTINGS_PREFIX - + "filter_securityindex_from_all_requests"; - public static final String SECURITY_DLS_MODE = SECURITY_SETTINGS_PREFIX + "dls.mode"; - // REST API - public static final String SECURITY_RESTAPI_ROLES_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.roles_enabled"; - public static final String SECURITY_RESTAPI_ADMIN_ENABLED = SECURITY_SETTINGS_PREFIX + "restapi.admin.enabled"; - public static final String SECURITY_RESTAPI_ENDPOINTS_DISABLED = SECURITY_SETTINGS_PREFIX + "restapi.endpoints_disabled"; - public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX = SECURITY_SETTINGS_PREFIX + "restapi.password_validation_regex"; - public static final String SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE = SECURITY_SETTINGS_PREFIX - + "restapi.password_validation_error_message"; - public static final String SECURITY_RESTAPI_PASSWORD_MIN_LENGTH = SECURITY_SETTINGS_PREFIX + "restapi.password_min_length"; - public static final String SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH = SECURITY_SETTINGS_PREFIX - + "restapi.password_score_based_validation_strength"; - // Illegal Opcodes from here on - public static final String SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX - + "unsupported.disable_rest_auth_initially"; - public static final String SECURITY_UNSUPPORTED_DELAY_INITIALIZATION_SECONDS = SECURITY_SETTINGS_PREFIX - + "unsupported.delay_initialization_seconds"; - public static final String SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX - + "unsupported.disable_intertransport_auth_initially"; - public static final String SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY = SECURITY_SETTINGS_PREFIX - + "unsupported.passive_intertransport_auth_initially"; - public static final String SECURITY_UNSUPPORTED_RESTORE_SECURITYINDEX_ENABLED = SECURITY_SETTINGS_PREFIX - + "unsupported.restore.securityindex.enabled"; - public static final String SECURITY_UNSUPPORTED_INJECT_USER_ENABLED = SECURITY_SETTINGS_PREFIX + "unsupported.inject_user.enabled"; - public static final String SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED = SECURITY_SETTINGS_PREFIX - + "unsupported.inject_user.admin.enabled"; - public static final String SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS = SECURITY_SETTINGS_PREFIX + "unsupported.allow_now_in_dls"; - - public static final String SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION = SECURITY_SETTINGS_PREFIX - + "unsupported.restapi.allow_securityconfig_modification"; - public static final String SECURITY_UNSUPPORTED_LOAD_STATIC_RESOURCES = SECURITY_SETTINGS_PREFIX + "unsupported.load_static_resources"; - public static final String SECURITY_UNSUPPORTED_ACCEPT_INVALID_CONFIG = SECURITY_SETTINGS_PREFIX + "unsupported.accept_invalid_config"; - - public static final String SECURITY_PROTECTED_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.enabled"; - public static final Boolean SECURITY_PROTECTED_INDICES_ENABLED_DEFAULT = false; - public static final String SECURITY_PROTECTED_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.indices"; - public static final List SECURITY_PROTECTED_INDICES_DEFAULT = Collections.emptyList(); - public static final String SECURITY_PROTECTED_INDICES_ROLES_KEY = SECURITY_SETTINGS_PREFIX + "protected_indices.roles"; - public static final List SECURITY_PROTECTED_INDICES_ROLES_DEFAULT = Collections.emptyList(); - - // Roles injection for plugins - public static final String OPENDISTRO_SECURITY_INJECTED_ROLES = "opendistro_security_injected_roles"; - public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_HEADER = "opendistro_security_injected_roles_header"; - - // Roles validation for the plugins - public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION = "opendistro_security_injected_roles_validation"; - public static final String OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION_HEADER = - "opendistro_security_injected_roles_validation_header"; - - // System indices settings - public static final String SYSTEM_INDEX_PERMISSION = "system:admin/system_index"; - public static final String SECURITY_SYSTEM_INDICES_ENABLED_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.enabled"; - public static final Boolean SECURITY_SYSTEM_INDICES_ENABLED_DEFAULT = false; - public static final String SECURITY_SYSTEM_INDICES_PERMISSIONS_ENABLED_KEY = SECURITY_SETTINGS_PREFIX - + "system_indices.permission.enabled"; - public static final Boolean SECURITY_SYSTEM_INDICES_PERMISSIONS_DEFAULT = false; - public static final String SECURITY_SYSTEM_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.indices"; - public static final List SECURITY_SYSTEM_INDICES_DEFAULT = Collections.emptyList(); - public static final String SECURITY_MASKED_FIELDS_ALGORITHM_DEFAULT = SECURITY_SETTINGS_PREFIX + "masked_fields.algorithm.default"; - - public static final String TENANCY_PRIVATE_TENANT_NAME = "private"; - public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; - public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; - - public static final String USE_JDK_SERIALIZATION = SECURITY_SETTINGS_PREFIX + "use_jdk_serialization"; - - // On-behalf-of endpoints settings - // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings - public static final String EXTENSIONS_BWC_PLUGIN_MODE = "bwcPluginMode"; - public static final boolean EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT = false; - // CS-ENFORCE-SINGLE - - // Variable for initial admin password support - public static final String OPENSEARCH_INITIAL_ADMIN_PASSWORD = "OPENSEARCH_INITIAL_ADMIN_PASSWORD"; - - // Resource sharing feature-flag - public static final String OPENSEARCH_RESOURCE_SHARING_ENABLED = SECURITY_SETTINGS_PREFIX + "resource_sharing.enabled"; - public static final boolean OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT = true; - - public static Set getSettingAsSet( - final Settings settings, - final String key, - final List defaultList, - final boolean ignoreCaseForNone - ) { - final List list = settings.getAsList(key, defaultList); - if (list.size() == 1 && "NONE".equals(ignoreCaseForNone ? list.get(0).toUpperCase() : list.get(0))) { - return Collections.emptySet(); - } - return ImmutableSet.copyOf(list); - } -} diff --git a/src/main/java/org/opensearch/security/support/ConfigHelper.java b/src/main/java/org/opensearch/security/support/ConfigHelper.java index d2cb6fc8ff..5faa58a17c 100644 --- a/src/main/java/org/opensearch/security/support/ConfigHelper.java +++ b/src/main/java/org/opensearch/security/support/ConfigHelper.java @@ -49,7 +49,7 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.engine.VersionConflictEngineException; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.Meta; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; diff --git a/src/main/java/org/opensearch/security/support/HTTPHelper.java b/src/main/java/org/opensearch/security/support/HTTPHelper.java index 10763ce35b..931e0a1912 100644 --- a/src/main/java/org/opensearch/security/support/HTTPHelper.java +++ b/src/main/java/org/opensearch/security/support/HTTPHelper.java @@ -33,8 +33,9 @@ import org.apache.logging.log4j.Logger; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; -import org.opensearch.security.user.AuthCredentials; public class HTTPHelper { diff --git a/src/main/java/org/opensearch/security/support/HeaderHelper.java b/src/main/java/org/opensearch/security/support/HeaderHelper.java index 3b237f5891..3d30b57514 100644 --- a/src/main/java/org/opensearch/security/support/HeaderHelper.java +++ b/src/main/java/org/opensearch/security/support/HeaderHelper.java @@ -33,7 +33,8 @@ import com.google.common.base.Strings; import org.opensearch.common.util.concurrent.ThreadContext; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; public class HeaderHelper { diff --git a/src/main/java/org/opensearch/security/support/HostAndCidrMatcher.java b/src/main/java/org/opensearch/security/support/HostAndCidrMatcher.java index caffa6b871..36c5ec02a2 100644 --- a/src/main/java/org/opensearch/security/support/HostAndCidrMatcher.java +++ b/src/main/java/org/opensearch/security/support/HostAndCidrMatcher.java @@ -18,6 +18,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.opensearch.security.common.support.WildcardMatcher; + import inet.ipaddr.IPAddressString; /** diff --git a/src/main/java/org/opensearch/security/support/JsonFlattener.java b/src/main/java/org/opensearch/security/support/JsonFlattener.java index ba2819a886..d7611c12a8 100644 --- a/src/main/java/org/opensearch/security/support/JsonFlattener.java +++ b/src/main/java/org/opensearch/security/support/JsonFlattener.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import org.opensearch.core.common.Strings; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; public class JsonFlattener { diff --git a/src/main/java/org/opensearch/security/support/SafeSerializationUtils.java b/src/main/java/org/opensearch/security/support/SafeSerializationUtils.java index de55334a99..9c5a28de81 100644 --- a/src/main/java/org/opensearch/security/support/SafeSerializationUtils.java +++ b/src/main/java/org/opensearch/security/support/SafeSerializationUtils.java @@ -25,7 +25,7 @@ import com.google.common.collect.ImmutableSet; import org.opensearch.security.auth.UserInjector; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import org.ldaptive.AbstractLdapBean; diff --git a/src/main/java/org/opensearch/security/support/SecurityIndexHandler.java b/src/main/java/org/opensearch/security/support/SecurityIndexHandler.java index d4d0c3f872..fc6ddb27da 100644 --- a/src/main/java/org/opensearch/security/support/SecurityIndexHandler.java +++ b/src/main/java/org/opensearch/security/support/SecurityIndexHandler.java @@ -40,7 +40,8 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.configuration.ConfigurationMap; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; diff --git a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java index ffd4fbd68a..d5eaaed143 100644 --- a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java +++ b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeType; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; public final class SecurityJsonNode { diff --git a/src/main/java/org/opensearch/security/support/SecuritySettings.java b/src/main/java/org/opensearch/security/support/SecuritySettings.java index 2a8bb079e8..d0bd4206b0 100644 --- a/src/main/java/org/opensearch/security/support/SecuritySettings.java +++ b/src/main/java/org/opensearch/security/support/SecuritySettings.java @@ -12,6 +12,7 @@ package org.opensearch.security.support; import org.opensearch.common.settings.Setting; +import org.opensearch.security.common.support.ConfigConstants; public class SecuritySettings { public static final Setting LEGACY_OPENDISTRO_SSL_DUAL_MODE_SETTING = Setting.boolSetting( diff --git a/src/main/java/org/opensearch/security/support/SecurityUtils.java b/src/main/java/org/opensearch/security/support/SecurityUtils.java index 5686f0076e..cc49081e71 100644 --- a/src/main/java/org/opensearch/security/support/SecurityUtils.java +++ b/src/main/java/org/opensearch/security/support/SecurityUtils.java @@ -36,6 +36,7 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.tools.Hasher; public final class SecurityUtils { diff --git a/src/main/java/org/opensearch/security/support/WildcardMatcher.java b/src/main/java/org/opensearch/security/support/WildcardMatcher.java deleted file mode 100644 index 537e2d473c..0000000000 --- a/src/main/java/org/opensearch/security/support/WildcardMatcher.java +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.support; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.regex.Pattern; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; - -public abstract class WildcardMatcher implements Predicate { - - public static final WildcardMatcher ANY = new WildcardMatcher() { - - @Override - public boolean matchAny(Stream candidates) { - return true; - } - - @Override - public boolean matchAny(Collection candidates) { - return true; - } - - @Override - public boolean matchAny(String... candidates) { - return true; - } - - @Override - public boolean matchAll(Stream candidates) { - return true; - } - - @Override - public boolean matchAll(Collection candidates) { - return true; - } - - @Override - public boolean matchAll(String[] candidates) { - return true; - } - - @Override - public > T getMatchAny(Stream candidates, Collector collector) { - return candidates.collect(collector); - } - - @Override - public boolean test(String candidate) { - return true; - } - - @Override - public String toString() { - return "*"; - } - }; - - public static final WildcardMatcher NONE = new WildcardMatcher() { - - @Override - public boolean matchAny(Stream candidates) { - return false; - } - - @Override - public boolean matchAny(Collection candidates) { - return false; - } - - @Override - public boolean matchAny(String... candidates) { - return false; - } - - @Override - public boolean matchAll(Stream candidates) { - return false; - } - - @Override - public boolean matchAll(Collection candidates) { - return false; - } - - @Override - public boolean matchAll(String[] candidates) { - return false; - } - - @Override - public > T getMatchAny(Stream candidates, Collector collector) { - return Stream.empty().collect(collector); - } - - @Override - public > T getMatchAny(Collection candidate, Collector collector) { - return Stream.empty().collect(collector); - } - - @Override - public > T getMatchAny(String[] candidate, Collector collector) { - return Stream.empty().collect(collector); - } - - @Override - public boolean test(String candidate) { - return false; - } - - @Override - public String toString() { - return ""; - } - }; - - public static WildcardMatcher from(String pattern, boolean caseSensitive) { - if (pattern == null) { - return NONE; - } else if (pattern.equals("*")) { - return ANY; - } else if (pattern.startsWith("/") && pattern.endsWith("/")) { - return new RegexMatcher(pattern, caseSensitive); - } else if (pattern.indexOf('?') >= 0 || pattern.indexOf('*') >= 0) { - return caseSensitive ? new SimpleMatcher(pattern) : new CasefoldingMatcher(pattern, SimpleMatcher::new); - } else { - return caseSensitive ? new Exact(pattern) : new CasefoldingMatcher(pattern, Exact::new); - } - } - - public static WildcardMatcher from(String pattern) { - return from(pattern, true); - } - - // This may in future use more optimized techniques to combine multiple WildcardMatchers in a single automaton - public static WildcardMatcher from(Stream stream, boolean caseSensitive) { - Collection matchers = stream.map(t -> { - if (t == null) { - return NONE; - } else if (t instanceof String) { - return WildcardMatcher.from(((String) t), caseSensitive); - } else if (t instanceof WildcardMatcher) { - return ((WildcardMatcher) t); - } - throw new UnsupportedOperationException("WildcardMatcher can't be constructed from " + t.getClass().getSimpleName()); - }).collect(ImmutableSet.toImmutableSet()); - - if (matchers.isEmpty()) { - return NONE; - } else if (matchers.size() == 1) { - return matchers.stream().findFirst().get(); - } - return new MatcherCombiner(matchers); - } - - public static WildcardMatcher from(Collection collection, boolean caseSensitive) { - if (collection == null || collection.isEmpty()) { - return NONE; - } else if (collection.size() == 1) { - T t = collection.stream().findFirst().get(); - if (t instanceof String) { - return from(((String) t), caseSensitive); - } else if (t instanceof WildcardMatcher) { - return ((WildcardMatcher) t); - } - throw new UnsupportedOperationException("WildcardMatcher can't be constructed from " + t.getClass().getSimpleName()); - } - return from(collection.stream(), caseSensitive); - } - - public static WildcardMatcher from(String[] patterns, boolean caseSensitive) { - if (patterns == null || patterns.length == 0) { - return NONE; - } else if (patterns.length == 1) { - return from(patterns[0], caseSensitive); - } - return from(Arrays.stream(patterns), caseSensitive); - } - - public static WildcardMatcher from(Stream patterns) { - return from(patterns, true); - } - - public static WildcardMatcher from(Collection patterns) { - return from(patterns, true); - } - - public static WildcardMatcher from(String... patterns) { - return from(patterns, true); - } - - public WildcardMatcher concat(Stream matchers) { - return new WildcardMatcher.MatcherCombiner(Stream.concat(matchers, Stream.of(this)).collect(ImmutableSet.toImmutableSet())); - } - - public WildcardMatcher concat(Collection matchers) { - if (matchers.isEmpty()) { - return this; - } - return concat(matchers.stream()); - } - - public WildcardMatcher concat(WildcardMatcher... matchers) { - if (matchers.length == 0) { - return this; - } - return concat(Arrays.stream(matchers)); - } - - public boolean matchAny(Stream candidates) { - return candidates.anyMatch(this); - } - - public boolean matchAny(Collection candidates) { - return matchAny(candidates.stream()); - } - - public boolean matchAny(String... candidates) { - return matchAny(Arrays.stream(candidates)); - } - - public boolean matchAll(Stream candidates) { - return candidates.allMatch(this); - } - - public boolean matchAll(Collection candidates) { - return matchAll(candidates.stream()); - } - - public boolean matchAll(String[] candidates) { - return matchAll(Arrays.stream(candidates)); - } - - public > T getMatchAny(Stream candidates, Collector collector) { - return candidates.filter(this).collect(collector); - } - - public > T getMatchAny(Collection candidate, Collector collector) { - return getMatchAny(candidate.stream(), collector); - } - - public > T getMatchAny(final String[] candidate, Collector collector) { - return getMatchAny(Arrays.stream(candidate), collector); - } - - public Optional findFirst(final String candidate) { - return Optional.ofNullable(test(candidate) ? this : null); - } - - public Iterable iterateMatching(Iterable candidates) { - return iterateMatching(candidates, Function.identity()); - } - - public Iterable iterateMatching(Iterable candidates, Function toStringFunction) { - return new Iterable() { - - @Override - public Iterator iterator() { - Iterator delegate = candidates.iterator(); - - return new Iterator() { - private E next; - - @Override - public boolean hasNext() { - if (next == null) { - init(); - } - - return next != null; - } - - @Override - public E next() { - if (next == null) { - init(); - } - - E result = next; - next = null; - return result; - } - - private void init() { - while (delegate.hasNext()) { - E candidate = delegate.next(); - - if (test(toStringFunction.apply(candidate))) { - next = candidate; - break; - } - } - } - }; - } - }; - } - - public static List matchers(Collection patterns) { - return patterns.stream().map(p -> WildcardMatcher.from(p, true)).collect(Collectors.toList()); - } - - public static List getAllMatchingPatterns(final Collection matchers, final String candidate) { - return matchers.stream().filter(p -> p.test(candidate)).map(Objects::toString).collect(Collectors.toList()); - } - - public static List getAllMatchingPatterns(final Collection pattern, final Collection candidates) { - return pattern.stream().filter(p -> p.matchAny(candidates)).map(Objects::toString).collect(Collectors.toList()); - } - - public static boolean isExact(String pattern) { - return pattern == null || !(pattern.contains("*") || pattern.contains("?") || (pattern.startsWith("/") && pattern.endsWith("/"))); - } - - // - // --- Implementation specializations --- - // - // Casefolding matcher - sits on top of case-sensitive matcher - // and proxies toLower() of input string to the wrapped matcher - private static final class CasefoldingMatcher extends WildcardMatcher { - - private final WildcardMatcher inner; - - public CasefoldingMatcher(String pattern, Function simpleWildcardMatcher) { - this.inner = simpleWildcardMatcher.apply(pattern.toLowerCase()); - } - - @Override - public boolean test(String candidate) { - return inner.test(candidate.toLowerCase()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - CasefoldingMatcher that = (CasefoldingMatcher) o; - return inner.equals(that.inner); - } - - @Override - public int hashCode() { - return inner.hashCode(); - } - - @Override - public String toString() { - return inner.toString(); - } - } - - public static final class Exact extends WildcardMatcher { - - private final String pattern; - - private Exact(String pattern) { - this.pattern = pattern; - } - - @Override - public boolean test(String candidate) { - return pattern.equals(candidate); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Exact that = (Exact) o; - return pattern.equals(that.pattern); - } - - @Override - public int hashCode() { - return pattern.hashCode(); - } - - @Override - public String toString() { - return pattern; - } - } - - // RegexMatcher uses JDK Pattern to test for matching, - // assumes "//" strings as input pattern - private static final class RegexMatcher extends WildcardMatcher { - - private final Pattern pattern; - - private RegexMatcher(String pattern, boolean caseSensitive) { - Preconditions.checkArgument(pattern.length() > 1 && pattern.startsWith("/") && pattern.endsWith("/")); - final String stripSlashesPattern = pattern.substring(1, pattern.length() - 1); - this.pattern = caseSensitive - ? Pattern.compile(stripSlashesPattern) - : Pattern.compile(stripSlashesPattern, Pattern.CASE_INSENSITIVE); - } - - @Override - public boolean test(String candidate) { - return pattern.matcher(candidate).matches(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - RegexMatcher that = (RegexMatcher) o; - return pattern.pattern().equals(that.pattern.pattern()); - } - - @Override - public int hashCode() { - return pattern.pattern().hashCode(); - } - - @Override - public String toString() { - return "/" + pattern.pattern() + "/"; - } - } - - // Simple implementation of WildcardMatcher matcher with * and ? without - // using exlicit stack or recursion (as long as we don't need sub-matches it does work) - // allows us to save on resources and heap allocations unless Regex is required - private static final class SimpleMatcher extends WildcardMatcher { - - private final String pattern; - - SimpleMatcher(String pattern) { - this.pattern = pattern; - } - - @Override - public boolean test(String candidate) { - int i = 0; - int j = 0; - int n = candidate.length(); - int m = pattern.length(); - int text_backup = -1; - int wild_backup = -1; - while (i < n) { - if (j < m && pattern.charAt(j) == '*') { - text_backup = i; - wild_backup = ++j; - } else if (j < m && (pattern.charAt(j) == '?' || pattern.charAt(j) == candidate.charAt(i))) { - i++; - j++; - } else { - if (wild_backup == -1) return false; - i = ++text_backup; - j = wild_backup; - } - } - while (j < m && pattern.charAt(j) == '*') - j++; - return j >= m; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SimpleMatcher that = (SimpleMatcher) o; - return pattern.equals(that.pattern); - } - - @Override - public int hashCode() { - return pattern.hashCode(); - } - - @Override - public String toString() { - return pattern; - } - } - - // MatcherCombiner is a combination of a set of matchers - // matches if any of the set do - // Empty MultiMatcher always returns false - private static final class MatcherCombiner extends WildcardMatcher { - - private final Collection wildcardMatchers; - private final int hashCode; - - MatcherCombiner(Collection wildcardMatchers) { - Preconditions.checkArgument(wildcardMatchers.size() > 1); - this.wildcardMatchers = wildcardMatchers; - hashCode = wildcardMatchers.hashCode(); - } - - @Override - public boolean test(String candidate) { - return wildcardMatchers.stream().anyMatch(m -> m.test(candidate)); - } - - @Override - public Optional findFirst(final String candidate) { - return wildcardMatchers.stream().filter(m -> m.test(candidate)).findFirst(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MatcherCombiner that = (MatcherCombiner) o; - return wildcardMatchers.equals(that.wildcardMatchers); - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public String toString() { - return wildcardMatchers.toString(); - } - } -} diff --git a/src/main/java/org/opensearch/security/support/YamlConfigReader.java b/src/main/java/org/opensearch/security/support/YamlConfigReader.java index c8096f744c..cf9d58b0d0 100644 --- a/src/main/java/org/opensearch/security/support/YamlConfigReader.java +++ b/src/main/java/org/opensearch/security/support/YamlConfigReader.java @@ -25,7 +25,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.xcontent.NamedXContentRegistry; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.Meta; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; diff --git a/src/main/java/org/opensearch/security/tools/AuditConfigMigrater.java b/src/main/java/org/opensearch/security/tools/AuditConfigMigrater.java index b01335a58f..ff58394869 100644 --- a/src/main/java/org/opensearch/security/tools/AuditConfigMigrater.java +++ b/src/main/java/org/opensearch/security/tools/AuditConfigMigrater.java @@ -29,8 +29,8 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; +import org.opensearch.security.common.support.DefaultObjectMapper; public class AuditConfigMigrater { diff --git a/src/main/java/org/opensearch/security/tools/Hasher.java b/src/main/java/org/opensearch/security/tools/Hasher.java index 21ad0a62df..6534218c39 100644 --- a/src/main/java/org/opensearch/security/tools/Hasher.java +++ b/src/main/java/org/opensearch/security/tools/Hasher.java @@ -31,9 +31,9 @@ import org.apache.commons.cli.*; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; -import org.opensearch.security.support.ConfigConstants; public class Hasher { diff --git a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java index 5eb9a98398..11c7870fea 100644 --- a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java +++ b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java @@ -122,11 +122,11 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.index.IndexNotFoundException; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.NonValidatingObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.ssl.util.ExceptionUtils; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.ConfigHelper; import org.opensearch.security.support.PemKeyReader; import org.opensearch.security.support.SecurityJsonNode; diff --git a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java index 572773095a..6beac3786b 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java @@ -27,16 +27,16 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.Strings; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.PasswordValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; -import org.opensearch.security.support.ConfigConstants; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; -import static org.opensearch.security.DefaultObjectMapper.YAML_MAPPER; +import static org.opensearch.security.common.support.DefaultObjectMapper.YAML_MAPPER; /** * This class updates the security related configuration, as needed. diff --git a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java index 02e11ae51b..6031e44eef 100644 --- a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java @@ -40,10 +40,10 @@ import org.opensearch.OpenSearchException; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.securityconf.DynamicConfigFactory; import org.opensearch.security.securityconf.NodesDnModel; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.transport.TransportRequest; import org.greenrobot.eventbus.Subscribe; diff --git a/src/main/java/org/opensearch/security/transport/OIDClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/OIDClusterRequestEvaluator.java index 72ffdb30b8..70a6f495ed 100644 --- a/src/main/java/org/opensearch/security/transport/OIDClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/OIDClusterRequestEvaluator.java @@ -30,7 +30,7 @@ import java.util.Arrays; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.transport.TransportRequest; // CS-SUPPRESS-SINGLE: RegexpSingleline Java Cryptography Extension is unrelated to OpenSearch extensions diff --git a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java index 7be544c9cd..a5bb58283b 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java +++ b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java @@ -56,16 +56,16 @@ import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.AuditLog.Origin; import org.opensearch.security.auth.BackendRegistry; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.privileges.dlsfls.DlsFlsLegacyHeaders; import org.opensearch.security.ssl.SslExceptionHandler; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.transport.SSLConfig; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; import org.opensearch.security.support.SerializationFormat; -import org.opensearch.security.user.User; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.Transport.Connection; import org.opensearch.transport.TransportException; diff --git a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java index 18c0c21282..255e0e2a7b 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java +++ b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java @@ -47,15 +47,15 @@ import org.opensearch.security.OpenSearchSecurityPlugin; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.AuditLog.Origin; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.SslExceptionHandler; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.transport.SSLConfig; import org.opensearch.security.ssl.transport.SecuritySSLRequestHandler; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.HeaderHelper; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportChannel; diff --git a/src/main/java/org/opensearch/security/user/AuthCredentials.java b/src/main/java/org/opensearch/security/user/AuthCredentials.java deleted file mode 100644 index beb3ae1733..0000000000 --- a/src/main/java/org/opensearch/security/user/AuthCredentials.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.user; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.opensearch.OpenSearchSecurityException; - -/** - * AuthCredentials are an abstraction to encapsulate credentials like passwords or generic - * native credentials like GSS tokens. - * - */ -public final class AuthCredentials { - - private static final String DIGEST_ALGORITHM = "SHA-256"; - private final String username; - private byte[] password; - private Object nativeCredentials; - private final Set securityRoles = new HashSet(); - private final Set backendRoles = new HashSet(); - private boolean complete; - private final byte[] internalPasswordHash; - private final Map attributes = new HashMap<>(); - - /** - * Create new credentials with a username and native credentials - * - * @param username The username, must not be null or empty - * @param nativeCredentials Arbitrary credentials (like GSS tokens), must not be null - * @throws IllegalArgumentException if username or nativeCredentials are null or empty - */ - public AuthCredentials(final String username, final Object nativeCredentials) { - this(username, null, nativeCredentials); - - if (nativeCredentials == null) { - throw new IllegalArgumentException("nativeCredentials must not be null or empty"); - } - } - - /** - * Create new credentials with a username and password - * - * @param username The username, must not be null or empty - * @param password The password, must not be null or empty - * @throws IllegalArgumentException if username or password is null or empty - */ - public AuthCredentials(final String username, final byte[] password) { - this(username, password, null); - - if (password == null || password.length == 0) { - throw new IllegalArgumentException("password must not be null or empty"); - } - } - - /** - * Create new credentials with a username, a initial optional set of roles and empty password/native credentials - - * @param username The username, must not be null or empty - * @param backendRoles set of roles this user is a member of - * @throws IllegalArgumentException if username is null or empty - */ - public AuthCredentials(final String username, String... backendRoles) { - this(username, null, null, backendRoles); - } - - /** - * Create new credentials with a username, a initial optional set of roles and empty password/native credentials - * @param username The username, must not be null or empty - * @param securityRoles The internal roles the user has been mapped to - * @param backendRoles set of roles this user is a member of - * @throws IllegalArgumentException if username is null or empty - */ - public AuthCredentials(final String username, List securityRoles, String... backendRoles) { - this(username, null, null, backendRoles); - this.securityRoles.addAll(securityRoles); - } - - private AuthCredentials(final String username, byte[] password, Object nativeCredentials, String... backendRoles) { - super(); - - if (username == null || username.isEmpty()) { - throw new IllegalArgumentException("username must not be null or empty"); - } - - this.username = username; - // make defensive copy - this.password = password == null ? null : Arrays.copyOf(password, password.length); - - if (this.password != null) { - try { - MessageDigest digester = MessageDigest.getInstance(DIGEST_ALGORITHM); - internalPasswordHash = digester.digest(this.password); - } catch (NoSuchAlgorithmException e) { - throw new OpenSearchSecurityException("Unable to digest password", e); - } - } else { - internalPasswordHash = null; - } - - if (password != null) { - Arrays.fill(password, (byte) '\0'); - password = null; - } - - this.nativeCredentials = nativeCredentials; - nativeCredentials = null; - - if (backendRoles != null && backendRoles.length > 0) { - this.backendRoles.addAll(Arrays.asList(backendRoles)); - } - } - - /** - * Wipe password and native credentials - */ - public void clearSecrets() { - if (password != null) { - Arrays.fill(password, (byte) '\0'); - password = null; - } - - nativeCredentials = null; - } - - public String getUsername() { - return username; - } - - /** - * - * @return Defensive copy of the password - */ - public byte[] getPassword() { - // make defensive copy - return password == null ? null : Arrays.copyOf(password, password.length); - } - - public Object getNativeCredentials() { - return nativeCredentials; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(internalPasswordHash); - result = prime * result + ((username == null) ? 0 : username.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - AuthCredentials other = (AuthCredentials) obj; - if (internalPasswordHash == null - || other.internalPasswordHash == null - || !MessageDigest.isEqual(internalPasswordHash, other.internalPasswordHash)) return false; - if (username == null) { - if (other.username != null) return false; - } else if (!username.equals(other.username)) return false; - return true; - } - - @Override - public String toString() { - return "AuthCredentials [username=" - + username - + ", password empty=" - + (password == null) - + ", nativeCredentials empty=" - + (nativeCredentials == null) - + ",backendRoles=" - + backendRoles - + "]"; - } - - /** - * - * @return Defensive copy of the roles this user is member of. - */ - public Set getBackendRoles() { - return new HashSet(backendRoles); - } - - /** - * - * @return Defensive copy of the security roles this user is member of. - */ - public Set getSecurityRoles() { - return Set.copyOf(securityRoles); - } - - public boolean isComplete() { - return complete; - } - - /** - * If the credentials are complete and no further roundtrips with the originator are due - * then this method must be called so that the authentication flow can proceed. - *

- * If this credentials are already marked a complete then a call to this method does nothing. - * - * @return this - */ - public AuthCredentials markComplete() { - this.complete = true; - return this; - } - - public void addAttribute(String name, String value) { - if (name != null && !name.isEmpty()) { - this.attributes.put(name, value); - } - } - - public Map getAttributes() { - return Collections.unmodifiableMap(this.attributes); - } -} diff --git a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java b/src/main/java/org/opensearch/security/user/CustomAttributesAware.java deleted file mode 100644 index f5db96db8a..0000000000 --- a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.user; - -import java.util.Map; - -public interface CustomAttributesAware { - - Map getCustomAttributesMap(); -} diff --git a/src/main/java/org/opensearch/security/user/User.java b/src/main/java/org/opensearch/security/user/User.java deleted file mode 100644 index 190729623d..0000000000 --- a/src/main/java/org/opensearch/security/user/User.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - -/* - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.security.user; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; - -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; - -/** - * A authenticated user and attributes associated to them (like roles, tenant, custom attributes) - *

- * Do not subclass from this class! - * - */ -public class User implements Serializable, Writeable, CustomAttributesAware { - - public static final User ANONYMOUS = new User( - "opendistro_security_anonymous", - Lists.newArrayList("opendistro_security_anonymous_backendrole"), - null - ); - - // This is a default user that is injected into a transport request when a user info is not present and passive_intertransport_auth is - // enabled. - // This is to be used in scenarios where some of the nodes do not have security enabled, and therefore do not pass any user information - // in threadcontext, yet we need the communication to not break between the nodes. - // Attach the required permissions to either the user or the backend role. - public static final User DEFAULT_TRANSPORT_USER = new User( - "opendistro_security_default_transport_user", - Lists.newArrayList("opendistro_security_default_transport_backendrole"), - null - ); - - private static final long serialVersionUID = -5500938501822658596L; - private final String name; - /** - * roles == backend_roles - */ - private final Set roles = Collections.synchronizedSet(new HashSet()); - private final Set securityRoles = Collections.synchronizedSet(new HashSet()); - private String requestedTenant; - private Map attributes = Collections.synchronizedMap(new HashMap<>()); - private boolean isInjected = false; - - public User(final StreamInput in) throws IOException { - super(); - name = in.readString(); - roles.addAll(in.readList(StreamInput::readString)); - requestedTenant = in.readString(); - if (requestedTenant.isEmpty()) { - requestedTenant = null; - } - attributes = Collections.synchronizedMap(in.readMap(StreamInput::readString, StreamInput::readString)); - securityRoles.addAll(in.readList(StreamInput::readString)); - } - - /** - * Create a new authenticated user - * - * @param name The username (must not be null or empty) - * @param roles Roles of which the user is a member off (maybe null) - * @param customAttributes Custom attributes associated with this (maybe null) - * @throws IllegalArgumentException if name is null or empty - */ - public User(final String name, final Collection roles, final AuthCredentials customAttributes) { - super(); - - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException("name must not be null or empty"); - } - - this.name = name; - - if (roles != null) { - this.addRoles(roles); - } - - if (customAttributes != null) { - this.attributes.putAll(customAttributes.getAttributes()); - } - - } - - /** - * Create a new authenticated user without roles and attributes - * - * @param name The username (must not be null or empty) - * @throws IllegalArgumentException if name is null or empty - */ - public User(final String name) { - this(name, null, null); - } - - public final String getName() { - return name; - } - - /** - * - * @return A unmodifiable set of the backend roles this user is a member of - */ - public final Set getRoles() { - return Collections.unmodifiableSet(roles); - } - - /** - * Associate this user with a backend role - * - * @param role The backend role - */ - public final void addRole(final String role) { - this.roles.add(role); - } - - /** - * Associate this user with a set of backend roles - * - * @param roles The backend roles - */ - public final void addRoles(final Collection roles) { - if (roles != null) { - this.roles.addAll(roles); - } - } - - /** - * Check if this user is a member of a backend role - * - * @param role The backend role - * @return true if this user is a member of the backend role, false otherwise - */ - public final boolean isUserInRole(final String role) { - return this.roles.contains(role); - } - - /** - * Associate this user with a set of custom attributes - * - * @param attributes custom attributes - */ - public final void addAttributes(final Map attributes) { - if (attributes != null) { - this.attributes.putAll(attributes); - } - } - - public final String getRequestedTenant() { - return requestedTenant; - } - - public final void setRequestedTenant(String requestedTenant) { - this.requestedTenant = requestedTenant; - } - - public boolean isInjected() { - return isInjected; - } - - public void setInjected(boolean isInjected) { - this.isInjected = isInjected; - } - - public final String toStringWithAttributes() { - return "User [name=" - + name - + ", backend_roles=" - + roles - + ", requestedTenant=" - + requestedTenant - + ", attributes=" - + attributes - + "]"; - } - - @Override - public final String toString() { - return "User [name=" + name + ", backend_roles=" + roles + ", requestedTenant=" + requestedTenant + "]"; - } - - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (name == null ? 0 : name.hashCode()); - return result; - } - - @Override - public final boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof User)) { - return false; - } - final User other = (User) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } - - /** - * Copy all backend roles from another user - * - * @param user The user from which the backend roles should be copied over - */ - public final void copyRolesFrom(final User user) { - if (user != null) { - this.addRoles(user.getRoles()); - } - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(name); - out.writeStringCollection(new ArrayList(roles)); - out.writeString(requestedTenant == null ? "" : requestedTenant); - out.writeMap(attributes, StreamOutput::writeString, StreamOutput::writeString); - out.writeStringCollection(securityRoles == null ? Collections.emptyList() : new ArrayList(securityRoles)); - } - - /** - * Get the custom attributes associated with this user - * - * @return A modifiable map with all the current custom attributes associated with this user - */ - public synchronized final Map getCustomAttributesMap() { - if (attributes == null) { - attributes = Collections.synchronizedMap(new HashMap<>()); - } - return attributes; - } - - public final void addSecurityRoles(final Collection securityRoles) { - if (securityRoles != null && this.securityRoles != null) { - this.securityRoles.addAll(securityRoles); - } - } - - public final Set getSecurityRoles() { - return this.securityRoles == null - ? Collections.synchronizedSet(Collections.emptySet()) - : Collections.unmodifiableSet(this.securityRoles); - } - - /** - * Check the custom attributes associated with this user - * - * @return true if it has a service account attributes, otherwise false - */ - public boolean isServiceAccount() { - Map userAttributesMap = this.getCustomAttributesMap(); - return userAttributesMap != null && "true".equals(userAttributesMap.get("attr.internal.service")); - } - - /** - * Check the custom attributes associated with this user - * - * @return true if it has a plugin account attributes, otherwise false - */ - public boolean isPluginUser() { - return name != null && name.startsWith("plugin:"); - } -} diff --git a/src/main/java/org/opensearch/security/user/UserService.java b/src/main/java/org/opensearch/security/user/UserService.java index d2289100f0..187c117738 100644 --- a/src/main/java/org/opensearch/security/user/UserService.java +++ b/src/main/java/org/opensearch/security/user/UserService.java @@ -42,7 +42,9 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.securityconf.DynamicConfigFactory; @@ -50,7 +52,6 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.InternalUserV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SecurityJsonNode; import org.opensearch.transport.client.Client; diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java index 96ee50bf6a..d071f12603 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java @@ -33,7 +33,7 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; import io.jsonwebtoken.JwtBuilder; diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java index 6253d2ca72..820b1df1c2 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java @@ -21,7 +21,7 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java index 6e3548926e..0b77095c44 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java index e7889aa825..245eb2efbb 100644 --- a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java @@ -50,12 +50,12 @@ import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; import org.opensearch.rest.RestResponse; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestFactory; import org.opensearch.security.filter.SecurityResponse; import org.opensearch.security.test.helper.file.FileHelper; -import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; import com.nimbusds.jwt.SignedJWT; diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java index 863db60e82..2d959b7232 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java index 0d9127b12e..0b3ed7144c 100755 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java @@ -24,10 +24,10 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.util.SSLConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend; import com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend; diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java index bf358b92ad..57a2768f2c 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java @@ -22,9 +22,9 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.user.AuthCredentials; import com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java index 5522501527..db679479ab 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java @@ -24,10 +24,10 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.util.SSLConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend; import com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend; diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java index 4eaa78392f..fe8b3be54a 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java index bb51ce00a6..551d918ec6 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java @@ -22,9 +22,9 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.user.AuthCredentials; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.util.ConfigConstants; diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java index dd19b383c2..3678a19976 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java @@ -31,11 +31,11 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.security.test.helper.file.FileHelper; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend; diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java index 41776e62d2..0b7e96a16e 100755 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java @@ -30,11 +30,11 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.security.test.helper.file.FileHelper; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend; diff --git a/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java b/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java index 99782324dc..434c13371d 100644 --- a/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java +++ b/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; import org.opensearch.security.test.helper.cluster.ClusterHelper; diff --git a/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java b/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java index b26546f92e..c9b50d58bb 100644 --- a/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java +++ b/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java @@ -15,7 +15,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.support.SecuritySettings; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/HttpIntegrationTests.java b/src/test/java/org/opensearch/security/HttpIntegrationTests.java index d76dfa3909..e4441d73b9 100644 --- a/src/test/java/org/opensearch/security/HttpIntegrationTests.java +++ b/src/test/java/org/opensearch/security/HttpIntegrationTests.java @@ -48,8 +48,8 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; @@ -59,7 +59,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.DefaultObjectMapper.readTree; +import static org.opensearch.security.common.support.DefaultObjectMapper.readTree; public class HttpIntegrationTests extends SingleClusterTest { diff --git a/src/test/java/org/opensearch/security/IndexIntegrationTests.java b/src/test/java/org/opensearch/security/IndexIntegrationTests.java index 91a92ab97d..3c4b470e71 100644 --- a/src/test/java/org/opensearch/security/IndexIntegrationTests.java +++ b/src/test/java/org/opensearch/security/IndexIntegrationTests.java @@ -47,7 +47,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.index.query.QueryBuilders; import org.opensearch.indices.InvalidIndexNameException; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.support.SecurityUtils; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; diff --git a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java index 306833ad61..00f880a627 100644 --- a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java +++ b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java @@ -51,8 +51,9 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterHelper; diff --git a/src/test/java/org/opensearch/security/IntegrationTests.java b/src/test/java/org/opensearch/security/IntegrationTests.java index 69e6ea8c7d..a4fd389bc7 100644 --- a/src/test/java/org/opensearch/security/IntegrationTests.java +++ b/src/test/java/org/opensearch/security/IntegrationTests.java @@ -46,9 +46,9 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.http.HTTPClientCertAuthenticator; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; @@ -60,7 +60,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.DefaultObjectMapper.readTree; +import static org.opensearch.security.common.support.DefaultObjectMapper.readTree; public class IntegrationTests extends SingleClusterTest { diff --git a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java index 89664b6a51..3663eed260 100644 --- a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java @@ -44,7 +44,7 @@ import org.opensearch.plugins.Plugin; import org.opensearch.repositories.RepositoriesService; import org.opensearch.script.ScriptService; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; diff --git a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java index 1c12cec61b..181e7ef501 100644 --- a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java @@ -38,7 +38,7 @@ import org.opensearch.plugins.Plugin; import org.opensearch.repositories.RepositoriesService; import org.opensearch.script.ScriptService; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; diff --git a/src/test/java/org/opensearch/security/SecurityAdminTests.java b/src/test/java/org/opensearch/security/SecurityAdminTests.java index 45c5c0e2a1..8eb7baffcd 100644 --- a/src/test/java/org/opensearch/security/SecurityAdminTests.java +++ b/src/test/java/org/opensearch/security/SecurityAdminTests.java @@ -30,8 +30,8 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/org/opensearch/security/SecurityRolesTests.java b/src/test/java/org/opensearch/security/SecurityRolesTests.java index e042fc6fa3..aee47a05f1 100644 --- a/src/test/java/org/opensearch/security/SecurityRolesTests.java +++ b/src/test/java/org/opensearch/security/SecurityRolesTests.java @@ -32,7 +32,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/SlowIntegrationTests.java b/src/test/java/org/opensearch/security/SlowIntegrationTests.java index 99ac9fb1b9..147dda44a4 100644 --- a/src/test/java/org/opensearch/security/SlowIntegrationTests.java +++ b/src/test/java/org/opensearch/security/SlowIntegrationTests.java @@ -42,8 +42,8 @@ import org.opensearch.common.unit.TimeValue; import org.opensearch.node.Node; import org.opensearch.node.PluginAwareNode; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; diff --git a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java index 896f477ca6..afed744425 100644 --- a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java +++ b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java @@ -33,7 +33,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/TracingTests.java b/src/test/java/org/opensearch/security/TracingTests.java index 2aee413e43..6ec61a5241 100644 --- a/src/test/java/org/opensearch/security/TracingTests.java +++ b/src/test/java/org/opensearch/security/TracingTests.java @@ -38,7 +38,7 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; diff --git a/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java b/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java index ff37fad282..fbdaa0c7c0 100644 --- a/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java +++ b/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java @@ -39,7 +39,7 @@ import org.opensearch.plugins.Plugin; import org.opensearch.repositories.RepositoriesService; import org.opensearch.script.ScriptService; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; diff --git a/src/test/java/org/opensearch/security/UserServiceUnitTests.java b/src/test/java/org/opensearch/security/UserServiceUnitTests.java index dc01f658d5..0856bfdc53 100644 --- a/src/test/java/org/opensearch/security/UserServiceUnitTests.java +++ b/src/test/java/org/opensearch/security/UserServiceUnitTests.java @@ -26,12 +26,12 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.user.UserFilterType; import org.opensearch.security.user.UserService; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/UtilTests.java b/src/test/java/org/opensearch/security/UtilTests.java index 15361b027c..da5d54f4de 100644 --- a/src/test/java/org/opensearch/security/UtilTests.java +++ b/src/test/java/org/opensearch/security/UtilTests.java @@ -31,11 +31,11 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.hasher.PasswordHasher; import org.opensearch.security.hasher.PasswordHasherFactory; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SecurityUtils; -import org.opensearch.security.support.WildcardMatcher; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogUnitTest.java b/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogUnitTest.java index 549fbf76b2..c486fd823f 100644 --- a/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogUnitTest.java +++ b/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogUnitTest.java @@ -17,10 +17,10 @@ import com.fasterxml.jackson.databind.JsonNode; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.routing.AuditMessageRouter; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java index 6896c3cda7..88565608c6 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java @@ -32,12 +32,12 @@ import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.config.AuditConfig; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; import org.opensearch.security.auditlog.integration.TestAuditlogImpl.MessagesNotFoundException; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java index d503ef3a3e..a35582b73d 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java @@ -21,9 +21,9 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; diff --git a/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java index 6f9bf6b29f..b8b9a0029c 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java @@ -20,10 +20,10 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; diff --git a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java index 3f0a5a57fc..9e4d2e3ff2 100644 --- a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java +++ b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java @@ -22,19 +22,19 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.config.AuditConfig.Filter.FilterEntries; -import org.opensearch.security.auditlog.impl.AuditCategory; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.auditlog.impl.AuditCategory.AUTHENTICATED; -import static org.opensearch.security.auditlog.impl.AuditCategory.BAD_HEADERS; -import static org.opensearch.security.auditlog.impl.AuditCategory.FAILED_LOGIN; -import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; -import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; -import static org.opensearch.security.auditlog.impl.AuditCategory.SSL_EXCEPTION; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.AUTHENTICATED; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.BAD_HEADERS; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.FAILED_LOGIN; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.SSL_EXCEPTION; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java index 3d4748c7db..4053bc2071 100644 --- a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java +++ b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java @@ -27,15 +27,15 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentFactory; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.auditlog.impl.AuditCategory.AUTHENTICATED; -import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.AUTHENTICATED; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java b/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java index 0f495d5063..de23f9116b 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java @@ -18,8 +18,8 @@ import org.opensearch.cluster.service.ClusterService; import org.opensearch.core.common.transport.TransportAddress; import org.opensearch.security.auditlog.AuditLog.Origin; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java b/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java index ddd1811ee4..af16130e51 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java @@ -22,10 +22,12 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.opensearch.security.common.auditlog.impl.AuditCategory; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.auditlog.impl.AuditCategory.AUTHENTICATED; -import static org.opensearch.security.auditlog.impl.AuditCategory.BAD_HEADERS; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.AUTHENTICATED; +import static org.opensearch.security.common.auditlog.impl.AuditCategory.BAD_HEADERS; @RunWith(Enclosed.class) public class AuditCategoryTest { diff --git a/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java b/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java index 21cd9ce968..da37a6eee6 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java @@ -34,6 +34,7 @@ import org.opensearch.rest.RestRequest; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auditlog.config.AuditConfig; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityRequestFactory; import org.opensearch.security.securityconf.impl.CType; diff --git a/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java index 80beb3fdfa..7b3cc7058d 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java @@ -24,8 +24,9 @@ import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.helper.RetrySink; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.filter.SecurityRequestChannel; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.transport.TransportRequest; diff --git a/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java b/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java index ba4ee7b55d..73fbd0e08c 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java @@ -32,7 +32,8 @@ import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.helper.MockRestRequest; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.transport.TransportRequest; diff --git a/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java b/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java index 47a5a155d2..f09d7cb490 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java @@ -25,8 +25,8 @@ import org.opensearch.core.common.transport.TransportAddress; import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.threadpool.ThreadPool; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/impl/TracingTests.java b/src/test/java/org/opensearch/security/auditlog/impl/TracingTests.java index 25a9971424..f0b85d7a77 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/TracingTests.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/TracingTests.java @@ -23,7 +23,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.auditlog.AuditTestUtils; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; diff --git a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java index 319c455a40..ae702c5e9a 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java @@ -33,10 +33,10 @@ import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.config.AuditConfig; import org.opensearch.security.auditlog.config.AuditConfig.Filter.FilterEntries; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.compliance.ComplianceConfig; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java index 236643174c..21fd1d6c7a 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java @@ -18,7 +18,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; import org.opensearch.security.test.helper.cluster.ClusterHelper; diff --git a/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java b/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java index 2f42f7a52f..4231b5ccb0 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java @@ -24,10 +24,10 @@ import org.opensearch.security.auditlog.helper.FailingSink; import org.opensearch.security.auditlog.helper.LoggingSink; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.sink.AuditLogSink; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java b/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java index 99b87ff9c6..0602313149 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java @@ -19,9 +19,9 @@ import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; import org.opensearch.security.auditlog.helper.LoggingSink; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; public class PerfTest extends AbstractAuditlogUnitTest { diff --git a/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java b/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java index 5ecdbe7e27..9d6070149a 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java @@ -22,13 +22,13 @@ import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; import org.opensearch.security.auditlog.helper.LoggingSink; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.sink.AuditLogSink; import org.opensearch.security.auditlog.sink.DebugSink; import org.opensearch.security.auditlog.sink.ExternalOpenSearchSink; import org.opensearch.security.auditlog.sink.InternalOpenSearchSink; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java b/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java index bb79ef5c20..2879ac982b 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java @@ -21,11 +21,11 @@ import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; import org.opensearch.security.auditlog.config.ThreadPoolConfig; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.sink.AuditLogSink; import org.opensearch.security.auditlog.sink.DebugSink; import org.opensearch.security.auditlog.sink.ExternalOpenSearchSink; import org.opensearch.security.auditlog.sink.InternalOpenSearchSink; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.security.test.helper.file.FileHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/sink/InternalOpensearchDataStreamSinkTest.java b/src/test/java/org/opensearch/security/auditlog/sink/InternalOpensearchDataStreamSinkTest.java index 4e44e866e9..774f058a92 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/InternalOpensearchDataStreamSinkTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/InternalOpensearchDataStreamSinkTest.java @@ -18,7 +18,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.unit.TimeValue; import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java b/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java index b1dec5d2cf..0a8e4cb629 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java @@ -27,7 +27,7 @@ import org.opensearch.common.xcontent.yaml.YamlXContent; import org.opensearch.security.auditlog.AbstractAuditlogUnitTest; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.security.test.helper.file.FileHelper; import org.springframework.kafka.test.rule.EmbeddedKafkaRule; diff --git a/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java b/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java index b8ae9318d5..529bc075d8 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java @@ -32,8 +32,8 @@ import org.opensearch.common.settings.Settings.Builder; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; import org.opensearch.security.auditlog.helper.TestHttpHandler; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; +import org.opensearch.security.common.auditlog.impl.AuditCategory; import org.opensearch.security.test.helper.file.FileHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java b/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java index ff8d2f2a79..bbd5f2c408 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java @@ -37,11 +37,11 @@ import org.opensearch.security.auditlog.helper.LoggingSink; import org.opensearch.security.auditlog.helper.MockAuditMessageFactory; import org.opensearch.security.auditlog.helper.TestHttpHandler; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.sink.WebhookSink.WebhookFormat; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java b/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java index 3c4e55ca16..4e037b354a 100644 --- a/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java +++ b/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java @@ -23,10 +23,10 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.internal.InternalAuthenticationBackend; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.hasher.PasswordHasherFactory; import org.opensearch.security.securityconf.InternalUsersModel; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.AuthCredentials; import org.mockito.Mockito; diff --git a/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java b/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java index 26b033729a..fce2c59cda 100644 --- a/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java +++ b/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java @@ -25,15 +25,15 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportRequest; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; import static org.mockito.Mockito.mock; public class RolesInjectorTest { diff --git a/src/test/java/org/opensearch/security/auth/UserInjectorTest.java b/src/test/java/org/opensearch/security/auth/UserInjectorTest.java index 74b48d54e5..e5e512f3e6 100644 --- a/src/test/java/org/opensearch/security/auth/UserInjectorTest.java +++ b/src/test/java/org/opensearch/security/auth/UserInjectorTest.java @@ -21,9 +21,9 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.http.XFFResolver; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportRequest; diff --git a/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java b/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java index 07bac9e349..d72fb21952 100644 --- a/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java +++ b/src/test/java/org/opensearch/security/auth/UserSubjectImplTests.java @@ -22,7 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_USER; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_USER; import static org.junit.Assert.assertNull; public class UserSubjectImplTests { diff --git a/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java b/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java index a8285c42a7..c460aa4099 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.user.AuthCredentials; +import org.opensearch.security.common.user.AuthCredentials; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java index ca8b4ad14d..823018e965 100644 --- a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java +++ b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java @@ -30,7 +30,7 @@ import org.opensearch.OpenSearchException; import org.opensearch.common.collect.Tuple; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.jwk.JWK; diff --git a/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java b/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java index 5e7980f431..9d6ca09f38 100644 --- a/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java +++ b/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java @@ -16,8 +16,8 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthenticationBackend; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; public class DummyAuthenticationBackend implements AuthenticationBackend { diff --git a/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java b/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java index 8f8a507cb8..67d7726999 100644 --- a/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java +++ b/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java @@ -16,8 +16,8 @@ import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; import org.opensearch.security.auth.AuthorizationBackend; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; public class DummyAuthorizer implements AuthorizationBackend { diff --git a/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java b/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java index 2cfd23fc23..9319e91b8a 100644 --- a/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java +++ b/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java @@ -18,9 +18,9 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auth.HTTPAuthenticator; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; public class DummyHTTPAuthenticator implements HTTPAuthenticator { diff --git a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java index 22dd99b011..42157316f4 100644 --- a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java +++ b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java @@ -48,8 +48,8 @@ import org.opensearch.node.PluginAwareNode; import org.opensearch.security.OpenSearchSecurityPlugin; import org.opensearch.security.RolesInjectorIntegTest; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.NodeSettingsSupplier; diff --git a/src/test/java/org/opensearch/security/configuration/ConfigurationRepositoryTest.java b/src/test/java/org/opensearch/security/configuration/ConfigurationRepositoryTest.java index cdc2f7d7e1..540892b596 100644 --- a/src/test/java/org/opensearch/security/configuration/ConfigurationRepositoryTest.java +++ b/src/test/java/org/opensearch/security/configuration/ConfigurationRepositoryTest.java @@ -30,11 +30,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.action.ActionListener; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.state.SecurityConfig; import org.opensearch.security.state.SecurityMetadata; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.support.SecurityIndexHandler; import org.opensearch.security.transport.SecurityInterceptorTests; import org.opensearch.threadpool.ThreadPool; @@ -50,8 +50,8 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; diff --git a/src/test/java/org/opensearch/security/configuration/SaltTest.java b/src/test/java/org/opensearch/security/configuration/SaltTest.java index 1a57a04629..2e9a3107f7 100644 --- a/src/test/java/org/opensearch/security/configuration/SaltTest.java +++ b/src/test/java/org/opensearch/security/configuration/SaltTest.java @@ -19,7 +19,7 @@ import org.opensearch.OpenSearchException; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java index 1d1eb1d430..c8da722e23 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java @@ -24,7 +24,7 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java index 208507d265..130d4e91b9 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java @@ -59,7 +59,7 @@ import org.opensearch.repositories.RepositoriesService; import org.opensearch.script.ScriptService; import org.opensearch.security.OpenSearchSecurityPlugin; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.tasks.Task; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java index 80a40ae442..c96ea7b87c 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java @@ -19,7 +19,7 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java index 86bf6d6009..d056bfffdd 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java @@ -18,7 +18,7 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java index 5c4ab36197..98e4127a7f 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java @@ -23,7 +23,7 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java index a2b0944cac..0a677b1ca8 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java @@ -20,7 +20,7 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AbstractApiActionValidationTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AbstractApiActionValidationTest.java index 9278551efa..a9f177b872 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AbstractApiActionValidationTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AbstractApiActionValidationTest.java @@ -25,7 +25,8 @@ import org.opensearch.common.xcontent.XContentFactory; import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.ToXContent; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.configuration.ConfigurationMap; import org.opensearch.security.configuration.ConfigurationRepository; import org.opensearch.security.hasher.PasswordHasher; @@ -33,7 +34,6 @@ import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.threadpool.ThreadPool; import org.mockito.Mock; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AbstractRestApiUnitTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AbstractRestApiUnitTest.java index 989e9933e9..e258f2e3bf 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AbstractRestApiUnitTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AbstractRestApiUnitTest.java @@ -23,8 +23,8 @@ import org.junit.Assert; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.AuditTestUtils; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.PasswordValidator; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; @@ -34,7 +34,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; public abstract class AbstractRestApiUnitTest extends SingleClusterTest { diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AllowlistApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AllowlistApiTest.java index ff8c1b9ce3..d378ddbb57 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AllowlistApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AllowlistApiTest.java @@ -22,20 +22,20 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.filter.SecurityRestFilter; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; import static org.junit.Assert.assertTrue; /** diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionRequestContentValidatorTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionRequestContentValidatorTest.java index 644d962589..e43906acec 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionRequestContentValidatorTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionRequestContentValidatorTest.java @@ -22,9 +22,9 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.common.bytes.BytesArray; import org.opensearch.core.rest.RestStatus; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.config.AuditConfig; -import org.opensearch.security.auditlog.impl.AuditCategory; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.compliance.ComplianceConfig; import org.opensearch.security.util.FakeRestRequest; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java index ffc7b4a22d..cccad84a56 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java @@ -32,9 +32,9 @@ import org.junit.rules.ExpectedException; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; import org.opensearch.security.auditlog.AuditTestUtils; import org.opensearch.security.auditlog.config.AuditConfig; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.compliance.ComplianceConfig; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper; @@ -42,9 +42,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.DefaultObjectMapper.readTree; -import static org.opensearch.security.DefaultObjectMapper.writeValueAsString; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; +import static org.opensearch.security.common.support.DefaultObjectMapper.readTree; +import static org.opensearch.security.common.support.DefaultObjectMapper.writeValueAsString; import static org.junit.Assert.assertTrue; public class AuditApiActionTest extends AbstractRestApiUnitTest { diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiActionUnitTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiActionUnitTest.java index 0251ee2f8a..2f9c091fda 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiActionUnitTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/ConfigUpgradeApiActionUnitTest.java @@ -26,8 +26,8 @@ import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestResponse; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.dlic.rest.support.Utils; +import org.opensearch.security.common.dlic.rest.support.Utils; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.ValidationResult; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java index 6b5678d822..b33768152f 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java @@ -18,7 +18,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java index fc09ffdae2..61389cafc9 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java @@ -15,7 +15,7 @@ import org.apache.http.HttpStatus; import org.junit.Test; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.support.SecurityJsonNode; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/InternalUsersApiActionValidationTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/InternalUsersApiActionValidationTest.java index ffe3461951..a3853dea26 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/InternalUsersApiActionValidationTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/InternalUsersApiActionValidationTest.java @@ -21,7 +21,8 @@ import org.opensearch.common.settings.Settings; import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.configuration.ConfigurationMap; import org.opensearch.security.dlic.rest.validation.ValidationResult; import org.opensearch.security.hasher.PasswordHasherFactory; @@ -29,7 +30,6 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.InternalUserV7; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.user.UserService; import org.opensearch.security.util.FakeRestRequest; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiTest.java index 752335b802..340636f3df 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/MultiTenancyConfigApiTest.java @@ -15,8 +15,8 @@ import org.apache.http.HttpStatus; import org.junit.Test; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.securityconf.impl.DashboardSignInOption; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java index 39e170331e..661e3b21f7 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java @@ -25,11 +25,11 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; @@ -37,7 +37,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class NodesDnApiTest extends AbstractRestApiUnitTest { private HttpResponse response; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RateLimitersApiActionValidationTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RateLimitersApiActionValidationTest.java index 6191a043ff..95472164fc 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RateLimitersApiActionValidationTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RateLimitersApiActionValidationTest.java @@ -18,7 +18,7 @@ import org.opensearch.core.common.bytes.BytesArray; import org.opensearch.core.rest.RestStatus; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.v7.ConfigV7; import org.opensearch.security.util.FakeRestRequest; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RequestHandlersBuilderTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RequestHandlersBuilderTest.java index 2ce636d0cc..8be7d2c2f2 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RequestHandlersBuilderTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RequestHandlersBuilderTest.java @@ -22,7 +22,7 @@ import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.ValidationResult; import org.opensearch.transport.client.Client; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluatorTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluatorTest.java index bbe1bf90f8..dfbd575ff8 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RestApiPrivilegesEvaluatorTest.java @@ -19,7 +19,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.rest.RestRequest; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.threadpool.ThreadPool; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java index 535bbb247e..2318824ca2 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java @@ -17,7 +17,7 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.support.SecurityJsonNode; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiActionValidationTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiActionValidationTest.java index a6832457b3..4526e9f097 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiActionValidationTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiActionValidationTest.java @@ -17,8 +17,8 @@ import org.opensearch.rest.RestRequest; import org.opensearch.security.util.FakeRestRequest; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; -import static org.opensearch.security.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigurationTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigurationTest.java index d88c0bc117..b801eacf1b 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigurationTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigurationTest.java @@ -17,7 +17,7 @@ import org.junit.Before; import org.junit.Test; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java index 2448ad0778..80f4e68555 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java index 5b5db93851..d17b863aa8 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java @@ -22,13 +22,13 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.security.auditlog.integration.TestAuditlogImpl; +import org.opensearch.security.common.auditlog.impl.AuditCategory; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.filter.SecurityRestFilter; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/dlic/rest/validation/EndpointValidatorTest.java b/src/test/java/org/opensearch/security/dlic/rest/validation/EndpointValidatorTest.java index d87fb9ee77..a08fc8da6b 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/validation/EndpointValidatorTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/validation/EndpointValidatorTest.java @@ -20,7 +20,7 @@ import org.junit.runner.RunWith; import org.opensearch.core.rest.RestStatus; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.dlic.rest.api.Endpoint; import org.opensearch.security.dlic.rest.api.RestApiAdminPrivilegesEvaluator; import org.opensearch.security.dlic.rest.api.SecurityConfiguration; diff --git a/src/test/java/org/opensearch/security/dlic/rest/validation/PasswordValidatorTest.java b/src/test/java/org/opensearch/security/dlic/rest/validation/PasswordValidatorTest.java index 7f8b631edb..6899a7ee11 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/validation/PasswordValidatorTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/validation/PasswordValidatorTest.java @@ -20,9 +20,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; -import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX; public class PasswordValidatorTest { diff --git a/src/test/java/org/opensearch/security/dlic/rest/validation/RequestContentValidatorTest.java b/src/test/java/org/opensearch/security/dlic/rest/validation/RequestContentValidatorTest.java index 72ad0ae76a..27bd2a6954 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/validation/RequestContentValidatorTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/validation/RequestContentValidatorTest.java @@ -33,7 +33,7 @@ import org.opensearch.http.HttpChannel; import org.opensearch.http.HttpRequest; import org.opensearch.rest.RestRequest; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; diff --git a/src/test/java/org/opensearch/security/filter/SecurityFilterTests.java b/src/test/java/org/opensearch/security/filter/SecurityFilterTests.java index 4f90a0865a..7ecedce7cc 100644 --- a/src/test/java/org/opensearch/security/filter/SecurityFilterTests.java +++ b/src/test/java/org/opensearch/security/filter/SecurityFilterTests.java @@ -25,14 +25,14 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.action.ActionResponse; import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.configuration.CompatConfig; import org.opensearch.security.configuration.DlsFlsRequestValve; import org.opensearch.security.http.XFFResolver; import org.opensearch.security.privileges.PrivilegesEvaluator; import org.opensearch.security.resolver.IndexResolverReplacer; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.threadpool.ThreadPool; import org.mockito.ArgumentCaptor; diff --git a/src/test/java/org/opensearch/security/filter/SecurityRestFilterUnitTests.java b/src/test/java/org/opensearch/security/filter/SecurityRestFilterUnitTests.java index bdeab0aa50..4f427e6bdc 100644 --- a/src/test/java/org/opensearch/security/filter/SecurityRestFilterUnitTests.java +++ b/src/test/java/org/opensearch/security/filter/SecurityRestFilterUnitTests.java @@ -26,7 +26,7 @@ import org.opensearch.rest.RestRequest; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auth.BackendRegistry; -import org.opensearch.security.configuration.AdminDNs; +import org.opensearch.security.common.configuration.AdminDNs; import org.opensearch.security.configuration.CompatConfig; import org.opensearch.security.privileges.RestLayerPrivilegesEvaluator; import org.opensearch.security.ssl.transport.PrincipalExtractor; diff --git a/src/test/java/org/opensearch/security/hasher/BCryptPasswordHasherTests.java b/src/test/java/org/opensearch/security/hasher/BCryptPasswordHasherTests.java index ee950f1058..ec41f7a85d 100644 --- a/src/test/java/org/opensearch/security/hasher/BCryptPasswordHasherTests.java +++ b/src/test/java/org/opensearch/security/hasher/BCryptPasswordHasherTests.java @@ -14,7 +14,7 @@ import org.junit.Before; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/hasher/PBKDF2PasswordHasherTests.java b/src/test/java/org/opensearch/security/hasher/PBKDF2PasswordHasherTests.java index 6d54173a10..0cff97403a 100644 --- a/src/test/java/org/opensearch/security/hasher/PBKDF2PasswordHasherTests.java +++ b/src/test/java/org/opensearch/security/hasher/PBKDF2PasswordHasherTests.java @@ -14,7 +14,7 @@ import org.junit.Before; import org.junit.Test; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/hasher/PasswordHasherFactoryTests.java b/src/test/java/org/opensearch/security/hasher/PasswordHasherFactoryTests.java index 81e250438e..50ff91e6c5 100644 --- a/src/test/java/org/opensearch/security/hasher/PasswordHasherFactoryTests.java +++ b/src/test/java/org/opensearch/security/hasher/PasswordHasherFactoryTests.java @@ -14,7 +14,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java b/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java index 0220bd37af..b5e5433394 100644 --- a/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java +++ b/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java @@ -38,9 +38,9 @@ import org.opensearch.SpecialPermission; import org.opensearch.common.settings.Settings; import org.opensearch.security.authtoken.jwt.EncryptionDecryptionUtil; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequest; import org.opensearch.security.filter.SecurityResponse; -import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; import io.jsonwebtoken.JwtBuilder; diff --git a/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java b/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java index 44065f819e..09f6e7b393 100644 --- a/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java +++ b/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java @@ -47,10 +47,10 @@ import org.opensearch.http.HttpResponse; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.AuthCredentials; import org.opensearch.security.filter.SecurityRequestChannel; import org.opensearch.security.filter.SecurityRequestFactory; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.AuthCredentials; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/src/test/java/org/opensearch/security/identity/ContextProvidingPluginSubjectTests.java b/src/test/java/org/opensearch/security/identity/ContextProvidingPluginSubjectTests.java index a719fc716e..335988fce0 100644 --- a/src/test/java/org/opensearch/security/identity/ContextProvidingPluginSubjectTests.java +++ b/src/test/java/org/opensearch/security/identity/ContextProvidingPluginSubjectTests.java @@ -17,13 +17,13 @@ import org.opensearch.plugins.IdentityAwarePlugin; import org.opensearch.plugins.Plugin; import org.opensearch.security.auth.UserSubjectImplTests; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; import org.opensearch.threadpool.TestThreadPool; import org.opensearch.threadpool.ThreadPool; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_USER; +import static org.opensearch.security.common.support.ConfigConstants.OPENDISTRO_SECURITY_USER; import static org.junit.Assert.assertNull; public class ContextProvidingPluginSubjectTests { diff --git a/src/test/java/org/opensearch/security/identity/SecurityTokenManagerTest.java b/src/test/java/org/opensearch/security/identity/SecurityTokenManagerTest.java index d686b145b2..4dc2b9bb23 100644 --- a/src/test/java/org/opensearch/security/identity/SecurityTokenManagerTest.java +++ b/src/test/java/org/opensearch/security/identity/SecurityTokenManagerTest.java @@ -30,10 +30,10 @@ import org.opensearch.identity.tokens.OnBehalfOfClaims; import org.opensearch.security.authtoken.jwt.ExpiringBearerAuthToken; import org.opensearch.security.authtoken.jwt.JwtVendor; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.securityconf.ConfigModel; import org.opensearch.security.securityconf.DynamicConfigModel; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.security.user.UserService; import org.opensearch.threadpool.ThreadPool; diff --git a/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java b/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java index 1373aa1741..946a6d75f9 100644 --- a/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java +++ b/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java @@ -27,9 +27,9 @@ import org.opensearch.action.support.WriteRequest.RefreshPolicy; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.XContentType; -import org.opensearch.security.DefaultObjectMapper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java index da35226d62..499b14bfc3 100644 --- a/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java @@ -32,12 +32,12 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.NullAuditLog; +import org.opensearch.security.common.user.User; import org.opensearch.security.securityconf.ConfigModel; import org.opensearch.security.securityconf.DynamicConfigModel; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.user.User; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; diff --git a/src/test/java/org/opensearch/security/privileges/SystemIndexAccessEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/SystemIndexAccessEvaluatorTest.java index 878033fd5c..2479ac0cad 100644 --- a/src/test/java/org/opensearch/security/privileges/SystemIndexAccessEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/SystemIndexAccessEvaluatorTest.java @@ -33,14 +33,14 @@ import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.resolver.IndexResolverReplacer; import org.opensearch.security.resolver.IndexResolverReplacer.Resolved; import org.opensearch.security.securityconf.FlattenedActionGroups; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; import org.opensearch.security.securityconf.impl.v7.RoleV7; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.security.util.MockIndexMetadataBuilder; import org.opensearch.tasks.Task; @@ -49,7 +49,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.support.ConfigConstants.SYSTEM_INDEX_PERMISSION; +import static org.opensearch.security.common.support.ConfigConstants.SYSTEM_INDEX_PERMISSION; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java b/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java index fc5c72ec44..eae11ea332 100644 --- a/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java +++ b/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java @@ -48,7 +48,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfigurationTest.java b/src/test/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfigurationTest.java index c554784581..b35acdf96e 100644 --- a/src/test/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfigurationTest.java +++ b/src/test/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfigurationTest.java @@ -19,7 +19,7 @@ import org.junit.Before; import org.junit.Test; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; diff --git a/src/test/java/org/opensearch/security/securityconf/impl/v7/ConfigV7Test.java b/src/test/java/org/opensearch/security/securityconf/impl/v7/ConfigV7Test.java index df1835adff..2ec7c62ed2 100644 --- a/src/test/java/org/opensearch/security/securityconf/impl/v7/ConfigV7Test.java +++ b/src/test/java/org/opensearch/security/securityconf/impl/v7/ConfigV7Test.java @@ -18,7 +18,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; diff --git a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java index 170d6cc410..e2bcb7d407 100644 --- a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java +++ b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java @@ -37,8 +37,8 @@ import org.opensearch.node.Node; import org.opensearch.node.PluginAwareNode; import org.opensearch.security.OpenSearchSecurityPlugin; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper; diff --git a/src/test/java/org/opensearch/security/ssl/SSLTest.java b/src/test/java/org/opensearch/security/ssl/SSLTest.java index 4b35bcefd6..eaa7898ea5 100644 --- a/src/test/java/org/opensearch/security/ssl/SSLTest.java +++ b/src/test/java/org/opensearch/security/ssl/SSLTest.java @@ -52,9 +52,9 @@ import org.opensearch.node.Node; import org.opensearch.node.PluginAwareNode; import org.opensearch.security.OpenSearchSecurityPlugin; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.util.ExceptionUtils; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.AbstractSecurityUnitTest; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java b/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java index 86d1e45133..4b9f931d81 100644 --- a/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java +++ b/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java @@ -23,9 +23,9 @@ import org.junit.rules.TemporaryFolder; import org.opensearch.common.settings.Settings; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.cluster.ClusterConfiguration; diff --git a/src/test/java/org/opensearch/security/ssl/SslSettingsManagerTest.java b/src/test/java/org/opensearch/security/ssl/SslSettingsManagerTest.java index 1aa2c47eb3..a8dc396a38 100644 --- a/src/test/java/org/opensearch/security/ssl/SslSettingsManagerTest.java +++ b/src/test/java/org/opensearch/security/ssl/SslSettingsManagerTest.java @@ -31,6 +31,7 @@ import io.netty.handler.ssl.SslContext; import static org.hamcrest.MatcherAssert.assertThat; +import static org.opensearch.security.common.support.ConfigConstants.SECURITY_SSL_ONLY; import static org.opensearch.security.ssl.CertificatesUtils.privateKeyToPemObject; import static org.opensearch.security.ssl.CertificatesUtils.writePemContent; import static org.opensearch.security.ssl.util.SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE; @@ -56,7 +57,6 @@ import static org.opensearch.security.ssl.util.SSLConfigConstants.SSL_TRANSPORT_CLIENT_EXTENDED_PREFIX; import static org.opensearch.security.ssl.util.SSLConfigConstants.SSL_TRANSPORT_PREFIX; import static org.opensearch.security.ssl.util.SSLConfigConstants.SSL_TRANSPORT_SERVER_EXTENDED_PREFIX; -import static org.opensearch.security.support.ConfigConstants.SECURITY_SSL_ONLY; import static org.junit.Assert.assertThrows; public class SslSettingsManagerTest extends RandomizedTest { diff --git a/src/test/java/org/opensearch/security/support/Base64CustomHelperTest.java b/src/test/java/org/opensearch/security/support/Base64CustomHelperTest.java index a5151be9fb..776b003473 100644 --- a/src/test/java/org/opensearch/security/support/Base64CustomHelperTest.java +++ b/src/test/java/org/opensearch/security/support/Base64CustomHelperTest.java @@ -25,8 +25,9 @@ import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.common.io.stream.Writeable; import org.opensearch.security.auth.UserInjector; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import org.ldaptive.LdapEntry; diff --git a/src/test/java/org/opensearch/security/support/Base64JDKHelperTest.java b/src/test/java/org/opensearch/security/support/Base64JDKHelperTest.java index 8737f5b6ac..663f49b5e2 100644 --- a/src/test/java/org/opensearch/security/support/Base64JDKHelperTest.java +++ b/src/test/java/org/opensearch/security/support/Base64JDKHelperTest.java @@ -25,8 +25,9 @@ import org.opensearch.OpenSearchException; import org.opensearch.action.search.SearchRequest; import org.opensearch.security.auth.UserInjector; -import org.opensearch.security.user.AuthCredentials; -import org.opensearch.security.user.User; +import org.opensearch.security.common.support.WildcardMatcher; +import org.opensearch.security.common.user.AuthCredentials; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import org.ldaptive.LdapEntry; diff --git a/src/test/java/org/opensearch/security/support/ConfigReaderTest.java b/src/test/java/org/opensearch/security/support/ConfigReaderTest.java index dfdfa76e75..46b910647c 100644 --- a/src/test/java/org/opensearch/security/support/ConfigReaderTest.java +++ b/src/test/java/org/opensearch/security/support/ConfigReaderTest.java @@ -18,7 +18,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.securityconf.impl.CType; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/src/test/java/org/opensearch/security/support/SafeSerializationUtilsTest.java b/src/test/java/org/opensearch/security/support/SafeSerializationUtilsTest.java index 187fd8b372..fcd418361d 100644 --- a/src/test/java/org/opensearch/security/support/SafeSerializationUtilsTest.java +++ b/src/test/java/org/opensearch/security/support/SafeSerializationUtilsTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.opensearch.security.auth.UserInjector; -import org.opensearch.security.user.User; +import org.opensearch.security.common.user.User; import com.amazon.dlic.auth.ldap.LdapUser; import org.ldaptive.AbstractLdapBean; diff --git a/src/test/java/org/opensearch/security/support/SecurityIndexHandlerTest.java b/src/test/java/org/opensearch/security/support/SecurityIndexHandlerTest.java index 5befb21012..953254f52f 100644 --- a/src/test/java/org/opensearch/security/support/SecurityIndexHandlerTest.java +++ b/src/test/java/org/opensearch/security/support/SecurityIndexHandlerTest.java @@ -43,7 +43,7 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.common.bytes.BytesArray; import org.opensearch.index.get.GetResult; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.configuration.ConfigurationMap; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.state.SecurityConfig; diff --git a/src/test/java/org/opensearch/security/system_indices/AbstractSystemIndicesTests.java b/src/test/java/org/opensearch/security/system_indices/AbstractSystemIndicesTests.java index 1fd8b88eed..137f322df4 100644 --- a/src/test/java/org/opensearch/security/system_indices/AbstractSystemIndicesTests.java +++ b/src/test/java/org/opensearch/security/system_indices/AbstractSystemIndicesTests.java @@ -30,7 +30,7 @@ import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java index 58f6d73ea8..0e3a6ca648 100644 --- a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java +++ b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java @@ -80,10 +80,10 @@ import org.opensearch.security.action.configupdate.ConfigUpdateAction; import org.opensearch.security.action.configupdate.ConfigUpdateRequest; import org.opensearch.security.action.configupdate.ConfigUpdateResponse; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.support.WildcardMatcher; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.security.ssl.util.SSLConfigConstants; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.support.WildcardMatcher; import org.opensearch.security.test.helper.cluster.ClusterHelper; import org.opensearch.security.test.helper.cluster.ClusterInfo; import org.opensearch.security.test.helper.file.FileHelper; 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 e80714c369..b4d50810d5 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 @@ -83,7 +83,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.opensearch.security.DefaultObjectMapper; +import org.opensearch.security.common.support.DefaultObjectMapper; import org.opensearch.security.test.helper.cluster.ClusterInfo; import org.opensearch.security.test.helper.file.FileHelper; diff --git a/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java b/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java index afb0e44f1e..296b85177d 100644 --- a/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java +++ b/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.tools.Hasher; import org.opensearch.security.tools.democonfig.util.NoExitSecurityManager; diff --git a/src/test/java/org/opensearch/security/transport/SecurityInterceptorTests.java b/src/test/java/org/opensearch/security/transport/SecurityInterceptorTests.java index d12fafb247..b3c800d8b9 100644 --- a/src/test/java/org/opensearch/security/transport/SecurityInterceptorTests.java +++ b/src/test/java/org/opensearch/security/transport/SecurityInterceptorTests.java @@ -33,13 +33,13 @@ import org.opensearch.security.OpenSearchSecurityPlugin; import org.opensearch.security.auditlog.AuditLog; import org.opensearch.security.auth.BackendRegistry; +import org.opensearch.security.common.support.ConfigConstants; +import org.opensearch.security.common.user.User; import org.opensearch.security.configuration.ClusterInfoHolder; import org.opensearch.security.ssl.SslExceptionHandler; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.transport.SSLConfig; import org.opensearch.security.support.Base64Helper; -import org.opensearch.security.support.ConfigConstants; -import org.opensearch.security.user.User; import org.opensearch.telemetry.tracing.noop.NoopTracer; import org.opensearch.test.transport.MockTransport; import org.opensearch.threadpool.ThreadPool; diff --git a/src/test/java/org/opensearch/security/transport/SecuritySSLRequestHandlerTests.java b/src/test/java/org/opensearch/security/transport/SecuritySSLRequestHandlerTests.java index c63c8d26ae..4b8d8bbe2c 100644 --- a/src/test/java/org/opensearch/security/transport/SecuritySSLRequestHandlerTests.java +++ b/src/test/java/org/opensearch/security/transport/SecuritySSLRequestHandlerTests.java @@ -18,11 +18,11 @@ import org.opensearch.Version; import org.opensearch.common.settings.Settings; import org.opensearch.core.transport.TransportResponse; +import org.opensearch.security.common.support.ConfigConstants; import org.opensearch.security.ssl.SslExceptionHandler; import org.opensearch.security.ssl.transport.PrincipalExtractor; import org.opensearch.security.ssl.transport.SSLConfig; import org.opensearch.security.ssl.transport.SecuritySSLRequestHandler; -import org.opensearch.security.support.ConfigConstants; import org.opensearch.tasks.Task; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportChannel; From 1d49b0e514b3c57773d6341c84578af5b42625d9 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 17 Mar 2025 19:50:02 -0400 Subject: [PATCH 4/4] Removes artistry introduced in #5186 Signed-off-by: Darshit Chanpura --- .../security/OpenSearchSecurityPlugin.java | 5 +---- .../security/auth/BackendRegistry.java | 20 +++---------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index a1145aa0c7..5d14114a7b 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -273,7 +273,6 @@ public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin private volatile RestLayerPrivilegesEvaluator restLayerEvaluator; private volatile ConfigurationRepository cr; private volatile AdminDNs adminDns; - private volatile org.opensearch.security.common.configuration.AdminDNs adminDNsCommon; private volatile ClusterService cs; private volatile AtomicReference localNode = new AtomicReference<>(); private volatile AuditLog auditLog; @@ -1138,7 +1137,6 @@ public Collection createComponents( sslExceptionHandler = new AuditLogSslExceptionHandler(auditLog); adminDns = new AdminDNs(settings); - adminDNsCommon = new org.opensearch.security.common.configuration.AdminDNs(settings); cr = ConfigurationRepository.create(settings, this.configPath, threadPool, localClient, clusterService, auditLog); @@ -1169,7 +1167,7 @@ public Collection createComponents( final var resourceSharingIndex = ResourceSharingConstants.OPENSEARCH_RESOURCE_SHARING_INDEX; ResourceSharingIndexHandler rsIndexHandler = new ResourceSharingIndexHandler(resourceSharingIndex, localClient, threadPool); - ResourceAccessHandler resourceAccessHandler = new ResourceAccessHandler(threadPool, rsIndexHandler, adminDNsCommon); + ResourceAccessHandler resourceAccessHandler = new ResourceAccessHandler(threadPool, rsIndexHandler, adminDns); resourceAccessHandler.initializeRecipientTypes(); // Resource Sharing index is enabled by default boolean isResourceSharingEnabled = settings.getAsBoolean( @@ -1258,7 +1256,6 @@ public Collection createComponents( } components.add(adminDns); - components.add(adminDNsCommon); components.add(cr); components.add(xffResolver); components.add(backendRegistry); diff --git a/src/main/java/org/opensearch/security/auth/BackendRegistry.java b/src/main/java/org/opensearch/security/auth/BackendRegistry.java index ce4610394b..766154a660 100644 --- a/src/main/java/org/opensearch/security/auth/BackendRegistry.java +++ b/src/main/java/org/opensearch/security/auth/BackendRegistry.java @@ -225,7 +225,7 @@ public boolean authenticate(final SecurityRequestChannel request) { if (adminDns.isAdminDN(sslPrincipal)) { // PKI authenticated REST call User superuser = new User(sslPrincipal); - UserSubject subject = new UserSubjectImpl(threadPool, new org.opensearch.security.common.user.User(sslPrincipal)); + UserSubject subject = new UserSubjectImpl(threadPool, superuser); threadContext.putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject); threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, superuser); return true; @@ -393,14 +393,7 @@ public boolean authenticate(final SecurityRequestChannel request) { final User effectiveUser = impersonatedUser == null ? authenticatedUser : impersonatedUser; threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, effectiveUser); - // TODO: The following artistry must be reverted when User class is completely moved to :opensearch-security-common - org.opensearch.security.common.user.User effUser = new org.opensearch.security.common.user.User( - effectiveUser.getName(), - effectiveUser.getRoles(), - null - ); - effUser.setAttributes(effectiveUser.getCustomAttributesMap()); - UserSubject subject = new UserSubjectImpl(threadPool, effUser); + UserSubject subject = new UserSubjectImpl(threadPool, effectiveUser); threadPool.getThreadContext().putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject); } else { if (isDebugEnabled) { @@ -428,14 +421,7 @@ public boolean authenticate(final SecurityRequestChannel request) { User anonymousUser = new User(User.ANONYMOUS.getName(), new HashSet(User.ANONYMOUS.getRoles()), null); anonymousUser.setRequestedTenant(tenant); - org.opensearch.security.common.user.User anonymousUserCommon = new org.opensearch.security.common.user.User( - User.ANONYMOUS.getName(), - new HashSet<>(User.ANONYMOUS.getRoles()), - null - ); - anonymousUserCommon.setRequestedTenant(tenant); - - UserSubject subject = new UserSubjectImpl(threadPool, anonymousUserCommon); + UserSubject subject = new UserSubjectImpl(threadPool, anonymousUser); threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, anonymousUser); threadPool.getThreadContext().putPersistent(ConfigConstants.OPENDISTRO_SECURITY_AUTHENTICATED_USER, subject);